Home | History | Annotate | Line # | Download | only in ixgbe
      1 /* $NetBSD: ixgbe_mbx.c,v 1.19 2022/01/25 01:56:22 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.19 2022/01/25 01:56:22 msaitoh Exp $");
     40 
     41 #include "ixgbe_type.h"
     42 #include "ixgbe_netbsd.h"
     43 #include "ixgbe_mbx.h"
     44 
     45 static s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id);
     46 static s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id);
     47 
     48 /**
     49  * ixgbe_read_mbx - Reads a message from the mailbox
     50  * @hw: pointer to the HW structure
     51  * @msg: The message buffer
     52  * @size: Length of buffer
     53  * @mbx_id: id of mailbox to read
     54  *
     55  * returns SUCCESS if it successfully read message from buffer
     56  **/
     57 s32 ixgbe_read_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
     58 {
     59 	struct ixgbe_mbx_info *mbx = &hw->mbx;
     60 
     61 	DEBUGFUNC("ixgbe_read_mbx");
     62 
     63 	/* limit read to size of mailbox */
     64 	if (size > mbx->size) {
     65 		ERROR_REPORT3(IXGBE_ERROR_ARGUMENT,
     66 			      "Invalid mailbox message size %u, changing to %u",
     67 			      size, mbx->size);
     68 		size = mbx->size;
     69 	}
     70 
     71 	if (mbx->ops[mbx_id].read)
     72 		return mbx->ops[mbx_id].read(hw, msg, size, mbx_id);
     73 
     74 	return IXGBE_ERR_CONFIG;
     75 }
     76 
     77 /**
     78  * ixgbe_poll_mbx - Wait for message and read it from the mailbox
     79  * @hw: pointer to the HW structure
     80  * @msg: The message buffer
     81  * @size: Length of buffer
     82  * @mbx_id: id of mailbox to read
     83  *
     84  * returns SUCCESS if it successfully read message from buffer
     85  **/
     86 s32 ixgbe_poll_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
     87 {
     88 	struct ixgbe_mbx_info *mbx = &hw->mbx;
     89 	s32 ret_val;
     90 
     91 	DEBUGFUNC("ixgbe_poll_mbx");
     92 
     93 	if (!mbx->ops[mbx_id].read || !mbx->ops[mbx_id].check_for_msg ||
     94 	    !mbx->timeout)
     95 		return IXGBE_ERR_CONFIG;
     96 
     97 	/* limit read to size of mailbox */
     98 	if (size > mbx->size) {
     99 		ERROR_REPORT3(IXGBE_ERROR_ARGUMENT,
    100 			      "Invalid mailbox message size %u, changing to %u",
    101 			      size, mbx->size);
    102 		size = mbx->size;
    103 	}
    104 
    105 	ret_val = ixgbe_poll_for_msg(hw, mbx_id);
    106 	/* if ack received read message, otherwise we timed out */
    107 	if (!ret_val)
    108 		return mbx->ops[mbx_id].read(hw, msg, size, mbx_id);
    109 
    110 	return ret_val;
    111 }
    112 
    113 /**
    114  * ixgbe_write_mbx - Write a message to the mailbox and wait for ACK
    115  * @hw: pointer to the HW structure
    116  * @msg: The message buffer
    117  * @size: Length of buffer
    118  * @mbx_id: id of mailbox to write
    119  *
    120  * returns SUCCESS if it successfully copied message into the buffer and
    121  * received an ACK to that message within specified period
    122  **/
    123 s32 ixgbe_write_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
    124 {
    125 	struct ixgbe_mbx_info *mbx = &hw->mbx;
    126 	s32 ret_val = IXGBE_ERR_MBX;
    127 
    128 	DEBUGFUNC("ixgbe_write_mbx");
    129 
    130 	/*
    131 	 * exit if either we can't write, release
    132 	 * or there is no timeout defined
    133 	 */
    134 	if (!mbx->ops[mbx_id].write || !mbx->ops[mbx_id].check_for_ack ||
    135 	    !mbx->ops[mbx_id].release || !mbx->timeout)
    136 		return IXGBE_ERR_CONFIG;
    137 
    138 	if (size > mbx->size) {
    139 		ret_val = IXGBE_ERR_PARAM;
    140 		ERROR_REPORT2(IXGBE_ERROR_ARGUMENT,
    141 			     "Invalid mailbox message size %u", size);
    142 	} else {
    143 		ret_val = mbx->ops[mbx_id].write(hw, msg, size, mbx_id);
    144 	}
    145 
    146 	return ret_val;
    147 }
    148 
    149 /**
    150  * ixgbe_check_for_msg - checks to see if someone sent us mail
    151  * @hw: pointer to the HW structure
    152  * @mbx_id: id of mailbox to check
    153  *
    154  * returns SUCCESS if the Status bit was found or else ERR_MBX
    155  **/
    156 s32 ixgbe_check_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
    157 {
    158 	struct ixgbe_mbx_info *mbx = &hw->mbx;
    159 	s32 ret_val = IXGBE_ERR_CONFIG;
    160 
    161 	DEBUGFUNC("ixgbe_check_for_msg");
    162 
    163 	if (mbx->ops[mbx_id].check_for_msg)
    164 		ret_val = mbx->ops[mbx_id].check_for_msg(hw, mbx_id);
    165 
    166 	return ret_val;
    167 }
    168 
    169 /**
    170  * ixgbe_check_for_ack - checks to see if someone sent us ACK
    171  * @hw: pointer to the HW structure
    172  * @mbx_id: id of mailbox to check
    173  *
    174  * returns SUCCESS if the Status bit was found or else ERR_MBX
    175  **/
    176 s32 ixgbe_check_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
    177 {
    178 	struct ixgbe_mbx_info *mbx = &hw->mbx;
    179 	s32 ret_val = IXGBE_ERR_CONFIG;
    180 
    181 	DEBUGFUNC("ixgbe_check_for_ack");
    182 
    183 	if (mbx->ops[mbx_id].check_for_ack)
    184 		ret_val = mbx->ops[mbx_id].check_for_ack(hw, mbx_id);
    185 
    186 	return ret_val;
    187 }
    188 
    189 /**
    190  * ixgbe_check_for_rst - checks to see if other side has reset
    191  * @hw: pointer to the HW structure
    192  * @mbx_id: id of mailbox to check
    193  *
    194  * returns SUCCESS if the Status bit was found or else ERR_MBX
    195  **/
    196 s32 ixgbe_check_for_rst(struct ixgbe_hw *hw, u16 mbx_id)
    197 {
    198 	struct ixgbe_mbx_info *mbx = &hw->mbx;
    199 	s32 ret_val = IXGBE_ERR_CONFIG;
    200 
    201 	DEBUGFUNC("ixgbe_check_for_rst");
    202 
    203 	if (mbx->ops[mbx_id].check_for_rst)
    204 		ret_val = mbx->ops[mbx_id].check_for_rst(hw, mbx_id);
    205 
    206 	return ret_val;
    207 }
    208 
    209 /**
    210  * ixgbe_clear_mbx - Clear Mailbox Memory
    211  * @hw: pointer to the HW structure
    212  * @mbx_id: id of mailbox to write
    213  *
    214  * Set VFMBMEM of given VF to 0x0.
    215  **/
    216 s32 ixgbe_clear_mbx(struct ixgbe_hw *hw, u16 mbx_id)
    217 {
    218 	struct ixgbe_mbx_info *mbx = &hw->mbx;
    219 	s32 ret_val = IXGBE_ERR_CONFIG;
    220 
    221 	DEBUGFUNC("ixgbe_clear_mbx");
    222 
    223 	if (mbx->ops[mbx_id].clear)
    224 		ret_val = mbx->ops[mbx_id].clear(hw, mbx_id);
    225 
    226 	return ret_val;
    227 }
    228 
    229 /**
    230  * ixgbe_poll_for_msg - Wait for message notification
    231  * @hw: pointer to the HW structure
    232  * @mbx_id: id of mailbox to write
    233  *
    234  * returns SUCCESS if it successfully received a message notification
    235  **/
    236 static s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
    237 {
    238 	struct ixgbe_mbx_info *mbx = &hw->mbx;
    239 	int countdown = mbx->timeout;
    240 
    241 	DEBUGFUNC("ixgbe_poll_for_msg");
    242 
    243 	if (!countdown || !mbx->ops[mbx_id].check_for_msg)
    244 		return IXGBE_ERR_CONFIG;
    245 
    246 	while (countdown && mbx->ops[mbx_id].check_for_msg(hw, mbx_id)) {
    247 		countdown--;
    248 		if (!countdown)
    249 			break;
    250 		usec_delay(mbx->usec_delay);
    251 	}
    252 
    253 	if (countdown == 0) {
    254 		ERROR_REPORT2(IXGBE_ERROR_POLLING,
    255 			   "Polling for VF%u mailbox message timedout", mbx_id);
    256 		return IXGBE_ERR_TIMEOUT;
    257 	}
    258 
    259 	return IXGBE_SUCCESS;
    260 }
    261 
    262 /**
    263  * ixgbe_poll_for_ack - Wait for message acknowledgment
    264  * @hw: pointer to the HW structure
    265  * @mbx_id: id of mailbox to write
    266  *
    267  * returns SUCCESS if it successfully received a message acknowledgment
    268  **/
    269 static s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
    270 {
    271 	struct ixgbe_mbx_info *mbx = &hw->mbx;
    272 	int countdown = mbx->timeout;
    273 
    274 	DEBUGFUNC("ixgbe_poll_for_ack");
    275 
    276 	if (!countdown || !mbx->ops[mbx_id].check_for_ack)
    277 		return IXGBE_ERR_CONFIG;
    278 
    279 	while (countdown && mbx->ops[mbx_id].check_for_ack(hw, mbx_id)) {
    280 		countdown--;
    281 		if (!countdown)
    282 			break;
    283 		usec_delay(mbx->usec_delay);
    284 	}
    285 
    286 	if (countdown == 0) {
    287 		ERROR_REPORT2(IXGBE_ERROR_POLLING,
    288 			     "Polling for VF%u mailbox ack timedout", mbx_id);
    289 		return IXGBE_ERR_TIMEOUT;
    290 	}
    291 
    292 	return IXGBE_SUCCESS;
    293 }
    294 
    295 
    296 /**
    297  * ixgbe_read_mailbox_vf - read VF's mailbox register
    298  * @hw: pointer to the HW structure
    299  *
    300  * This function is used to read the mailbox register dedicated for VF without
    301  * losing the read to clear status bits.
    302  **/
    303 static u32 ixgbe_read_mailbox_vf(struct ixgbe_hw *hw)
    304 {
    305 	u32 vf_mailbox = IXGBE_READ_REG(hw, IXGBE_VFMAILBOX);
    306 
    307 	vf_mailbox |= hw->mbx.vf_mailbox;
    308 	hw->mbx.vf_mailbox |= vf_mailbox & IXGBE_VFMAILBOX_R2C_BITS;
    309 
    310 	return vf_mailbox;
    311 }
    312 
    313 static void ixgbe_clear_msg_vf(struct ixgbe_hw *hw)
    314 {
    315 	u32 vf_mailbox = ixgbe_read_mailbox_vf(hw);
    316 
    317 	if (vf_mailbox & IXGBE_VFMAILBOX_PFSTS) {
    318 		IXGBE_EVC_ADD(&hw->mbx.stats.reqs, 1);
    319 		hw->mbx.vf_mailbox &= ~IXGBE_VFMAILBOX_PFSTS;
    320 	}
    321 }
    322 
    323 static void ixgbe_clear_ack_vf(struct ixgbe_hw *hw)
    324 {
    325 	u32 vf_mailbox = ixgbe_read_mailbox_vf(hw);
    326 
    327 	if (vf_mailbox & IXGBE_VFMAILBOX_PFACK) {
    328 		IXGBE_EVC_ADD(&hw->mbx.stats.acks, 1);
    329 		hw->mbx.vf_mailbox &= ~IXGBE_VFMAILBOX_PFACK;
    330 	}
    331 }
    332 
    333 static void ixgbe_clear_rst_vf(struct ixgbe_hw *hw)
    334 {
    335 	u32 vf_mailbox = ixgbe_read_mailbox_vf(hw);
    336 
    337 	if (vf_mailbox & (IXGBE_VFMAILBOX_RSTI | IXGBE_VFMAILBOX_RSTD)) {
    338 		IXGBE_EVC_ADD(&hw->mbx.stats.rsts, 1);
    339 		hw->mbx.vf_mailbox &= ~(IXGBE_VFMAILBOX_RSTI |
    340 					IXGBE_VFMAILBOX_RSTD);
    341 	}
    342 }
    343 
    344 /**
    345  * ixgbe_check_for_bit_vf - Determine if a status bit was set
    346  * @hw: pointer to the HW structure
    347  * @mask: bitmask for bits to be tested and cleared
    348  *
    349  * This function is used to check for the read to clear bits within
    350  * the V2P mailbox.
    351  **/
    352 static s32 ixgbe_check_for_bit_vf(struct ixgbe_hw *hw, u32 mask)
    353 {
    354 	u32 vf_mailbox = ixgbe_read_mailbox_vf(hw);
    355 
    356 	if (vf_mailbox & mask)
    357 		return IXGBE_SUCCESS;
    358 
    359 	return IXGBE_ERR_MBX;
    360 }
    361 
    362 /**
    363  * ixgbe_check_for_msg_vf - checks to see if the PF has sent mail
    364  * @hw: pointer to the HW structure
    365  * @mbx_id: id of mailbox to check
    366  *
    367  * returns SUCCESS if the PF has set the Status bit or else ERR_MBX
    368  **/
    369 static s32 ixgbe_check_for_msg_vf(struct ixgbe_hw *hw, u16 mbx_id)
    370 {
    371 	UNREFERENCED_1PARAMETER(mbx_id);
    372 	DEBUGFUNC("ixgbe_check_for_msg_vf");
    373 
    374 	if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFSTS)) {
    375 		IXGBE_EVC_ADD(&hw->mbx.stats.reqs, 1);
    376 		return IXGBE_SUCCESS;
    377 	}
    378 
    379 	return IXGBE_ERR_MBX;
    380 }
    381 
    382 /**
    383  * ixgbe_check_for_ack_vf - checks to see if the PF has ACK'd
    384  * @hw: pointer to the HW structure
    385  * @mbx_id: id of mailbox to check
    386  *
    387  * returns SUCCESS if the PF has set the ACK bit or else ERR_MBX
    388  **/
    389 static s32 ixgbe_check_for_ack_vf(struct ixgbe_hw *hw, u16 mbx_id)
    390 {
    391 	UNREFERENCED_1PARAMETER(mbx_id);
    392 	DEBUGFUNC("ixgbe_check_for_ack_vf");
    393 
    394 	if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFACK)) {
    395 		/* TODO: should this be autocleared? */
    396 		ixgbe_clear_ack_vf(hw);
    397 		IXGBE_EVC_ADD(&hw->mbx.stats.acks, 1);
    398 		return IXGBE_SUCCESS;
    399 	}
    400 
    401 	return IXGBE_ERR_MBX;
    402 }
    403 
    404 /**
    405  * ixgbe_check_for_rst_vf - checks to see if the PF has reset
    406  * @hw: pointer to the HW structure
    407  * @mbx_id: id of mailbox to check
    408  *
    409  * returns TRUE if the PF has set the reset done bit or else FALSE
    410  **/
    411 static s32 ixgbe_check_for_rst_vf(struct ixgbe_hw *hw, u16 mbx_id)
    412 {
    413 	UNREFERENCED_1PARAMETER(mbx_id);
    414 	DEBUGFUNC("ixgbe_check_for_rst_vf");
    415 
    416 	if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_RSTI |
    417 					  IXGBE_VFMAILBOX_RSTD)) {
    418 		/* TODO: should this be autocleared? */
    419 		ixgbe_clear_rst_vf(hw);
    420 		IXGBE_EVC_ADD(&hw->mbx.stats.rsts, 1);
    421 		return IXGBE_SUCCESS;
    422 	}
    423 
    424 	return IXGBE_ERR_MBX;
    425 }
    426 
    427 /**
    428  * ixgbe_obtain_mbx_lock_vf - obtain mailbox lock
    429  * @hw: pointer to the HW structure
    430  *
    431  * return SUCCESS if we obtained the mailbox lock
    432  **/
    433 static s32 ixgbe_obtain_mbx_lock_vf(struct ixgbe_hw *hw)
    434 {
    435 	struct ixgbe_mbx_info *mbx = &hw->mbx;
    436 	int countdown = mbx->timeout;
    437 	s32 ret_val = IXGBE_ERR_MBX;
    438 	u32 vf_mailbox;
    439 
    440 	DEBUGFUNC("ixgbe_obtain_mbx_lock_vf");
    441 
    442 	if (!mbx->timeout)
    443 		return IXGBE_ERR_CONFIG;
    444 
    445 	while (countdown--) {
    446 		/* Reserve mailbox for VF use */
    447 		vf_mailbox = ixgbe_read_mailbox_vf(hw);
    448 		vf_mailbox |= IXGBE_VFMAILBOX_VFU;
    449 		IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox);
    450 
    451 		/* Verify that VF is the owner of the lock */
    452 		if (ixgbe_read_mailbox_vf(hw) & IXGBE_VFMAILBOX_VFU) {
    453 			ret_val = IXGBE_SUCCESS;
    454 			break;
    455 		}
    456 
    457 		/* Wait a bit before trying again */
    458 		usec_delay(mbx->usec_delay);
    459 	}
    460 
    461 	if (ret_val != IXGBE_SUCCESS) {
    462 		ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
    463 				"Failed to obtain mailbox lock");
    464 		ret_val = IXGBE_ERR_TIMEOUT;
    465 	}
    466 
    467 	return ret_val;
    468 }
    469 
    470 /**
    471  * ixgbe_release_mbx_lock_dummy - release mailbox lock
    472  * @hw: pointer to the HW structure
    473  * @mbx_id: id of mailbox to read
    474  **/
    475 static void ixgbe_release_mbx_lock_dummy(struct ixgbe_hw *hw, u16 mbx_id)
    476 {
    477 	UNREFERENCED_2PARAMETER(hw, mbx_id);
    478 
    479 	DEBUGFUNC("ixgbe_release_mbx_lock_dummy");
    480 }
    481 
    482 /**
    483  * ixgbe_release_mbx_lock_vf - release mailbox lock
    484  * @hw: pointer to the HW structure
    485  * @mbx_id: id of mailbox to read
    486  **/
    487 static void ixgbe_release_mbx_lock_vf(struct ixgbe_hw *hw, u16 mbx_id)
    488 {
    489 	u32 vf_mailbox;
    490 
    491 	UNREFERENCED_1PARAMETER(mbx_id);
    492 
    493 	DEBUGFUNC("ixgbe_release_mbx_lock_vf");
    494 
    495 	/* Return ownership of the buffer */
    496 	vf_mailbox = ixgbe_read_mailbox_vf(hw);
    497 	vf_mailbox &= ~IXGBE_VFMAILBOX_VFU;
    498 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox);
    499 }
    500 
    501 /**
    502  * ixgbe_write_mbx_vf_legacy - Write a message to the mailbox
    503  * @hw: pointer to the HW structure
    504  * @msg: The message buffer
    505  * @size: Length of buffer
    506  * @mbx_id: id of mailbox to write
    507  *
    508  * returns SUCCESS if it successfully copied message into the buffer
    509  **/
    510 static s32 ixgbe_write_mbx_vf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size,
    511 				     u16 mbx_id)
    512 {
    513 	s32 ret_val;
    514 	u16 i;
    515 
    516 	UNREFERENCED_1PARAMETER(mbx_id);
    517 	DEBUGFUNC("ixgbe_write_mbx_vf_legacy");
    518 
    519 	/* lock the mailbox to prevent pf/vf race condition */
    520 	ret_val = ixgbe_obtain_mbx_lock_vf(hw);
    521 	if (ret_val)
    522 		return ret_val;
    523 
    524 	/* flush msg and acks as we are overwriting the message buffer */
    525 	ixgbe_check_for_msg_vf(hw, 0);
    526 	ixgbe_clear_msg_vf(hw);
    527 	ixgbe_check_for_ack_vf(hw, 0);
    528 	ixgbe_clear_ack_vf(hw);
    529 
    530 	/* copy the caller specified message to the mailbox memory buffer */
    531 	for (i = 0; i < size; i++)
    532 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFMBMEM, i, msg[i]);
    533 
    534 	/* update stats */
    535 	IXGBE_EVC_ADD(&hw->mbx.stats.msgs_tx, 1);
    536 
    537 	/* interrupt the PF to tell it a message has been sent */
    538 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_REQ);
    539 
    540 	return IXGBE_SUCCESS;
    541 }
    542 
    543 /**
    544  * ixgbe_write_mbx_vf - Write a message to the mailbox
    545  * @hw: pointer to the HW structure
    546  * @msg: The message buffer
    547  * @size: Length of buffer
    548  * @mbx_id: id of mailbox to write
    549  *
    550  * returns SUCCESS if it successfully copied message into the buffer
    551  **/
    552 static s32 ixgbe_write_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,
    553 			      u16 mbx_id)
    554 {
    555 	u32 vf_mailbox;
    556 	s32 ret_val;
    557 	u16 i;
    558 
    559 	UNREFERENCED_1PARAMETER(mbx_id);
    560 
    561 	DEBUGFUNC("ixgbe_write_mbx_vf");
    562 
    563 	/* lock the mailbox to prevent pf/vf race condition */
    564 	ret_val = ixgbe_obtain_mbx_lock_vf(hw);
    565 	if (ret_val)
    566 		goto out;
    567 
    568 	/* flush msg and acks as we are overwriting the message buffer */
    569 	ixgbe_clear_msg_vf(hw);
    570 	ixgbe_clear_ack_vf(hw);
    571 
    572 	/* copy the caller specified message to the mailbox memory buffer */
    573 	for (i = 0; i < size; i++)
    574 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFMBMEM, i, msg[i]);
    575 
    576 	/* update stats */
    577 	IXGBE_EVC_ADD(&hw->mbx.stats.msgs_tx, 1);
    578 
    579 	/* interrupt the PF to tell it a message has been sent */
    580 	vf_mailbox = ixgbe_read_mailbox_vf(hw);
    581 	vf_mailbox |= IXGBE_VFMAILBOX_REQ;
    582 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox);
    583 
    584 	/* if msg sent wait until we receive an ack */
    585 	ixgbe_poll_for_ack(hw, mbx_id);
    586 
    587 out:
    588 	hw->mbx.ops[mbx_id].release(hw, mbx_id);
    589 
    590 	return ret_val;
    591 }
    592 
    593 /**
    594  * ixgbe_read_mbx_vf_legacy - Reads a message from the inbox intended for vf
    595  * @hw: pointer to the HW structure
    596  * @msg: The message buffer
    597  * @size: Length of buffer
    598  * @mbx_id: id of mailbox to read
    599  *
    600  * returns SUCCESS if it successfully read message from buffer
    601  **/
    602 static s32 ixgbe_read_mbx_vf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size,
    603 				    u16 mbx_id)
    604 {
    605 	s32 ret_val;
    606 	u16 i;
    607 
    608 	DEBUGFUNC("ixgbe_read_mbx_vf_legacy");
    609 	UNREFERENCED_1PARAMETER(mbx_id);
    610 
    611 	/* lock the mailbox to prevent pf/vf race condition */
    612 	ret_val = ixgbe_obtain_mbx_lock_vf(hw);
    613 	if (ret_val)
    614 		return ret_val;
    615 
    616 	/* copy the message from the mailbox memory buffer */
    617 	for (i = 0; i < size; i++)
    618 		msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i);
    619 
    620 	/* Acknowledge receipt and release mailbox, then we're done */
    621 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_ACK);
    622 
    623 	/* update stats */
    624 	IXGBE_EVC_ADD(&hw->mbx.stats.msgs_rx, 1);
    625 
    626 	return IXGBE_SUCCESS;
    627 }
    628 
    629 /**
    630  * ixgbe_read_mbx_vf - Reads a message from the inbox intended for vf
    631  * @hw: pointer to the HW structure
    632  * @msg: The message buffer
    633  * @size: Length of buffer
    634  * @mbx_id: id of mailbox to read
    635  *
    636  * returns SUCCESS if it successfully read message from buffer
    637  **/
    638 static s32 ixgbe_read_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,
    639 			     u16 mbx_id)
    640 {
    641 	u32 vf_mailbox;
    642 	s32 ret_val;
    643 	u16 i;
    644 
    645 	DEBUGFUNC("ixgbe_read_mbx_vf");
    646 	UNREFERENCED_1PARAMETER(mbx_id);
    647 
    648 	/* check if there is a message from PF */
    649 	ret_val = ixgbe_check_for_msg_vf(hw, 0);
    650 	if (ret_val != IXGBE_SUCCESS)
    651 		return IXGBE_ERR_MBX_NOMSG;
    652 
    653 	ixgbe_clear_msg_vf(hw);
    654 
    655 	/* copy the message from the mailbox memory buffer */
    656 	for (i = 0; i < size; i++)
    657 		msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i);
    658 
    659 	/* Acknowledge receipt */
    660 	vf_mailbox = ixgbe_read_mailbox_vf(hw);
    661 	vf_mailbox |= IXGBE_VFMAILBOX_ACK;
    662 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox);
    663 
    664 	/* update stats */
    665 	IXGBE_EVC_ADD(&hw->mbx.stats.msgs_rx, 1);
    666 
    667 	return IXGBE_SUCCESS;
    668 }
    669 
    670 /**
    671  * ixgbe_init_mbx_params_vf - set initial values for vf mailbox
    672  * @hw: pointer to the HW structure
    673  *
    674  * Initializes single set the hw->mbx struct to correct values for vf mailbox
    675  * Set of legacy functions is being used here
    676  */
    677 void ixgbe_init_mbx_params_vf(struct ixgbe_hw *hw)
    678 {
    679 	struct ixgbe_mbx_info *mbx = &hw->mbx;
    680 
    681 	mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT;
    682 	mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;
    683 
    684 	mbx->size = IXGBE_VFMAILBOX_SIZE;
    685 
    686 	/* VF has only one mailbox connection, no need for more IDs */
    687 	mbx->ops[0].release = ixgbe_release_mbx_lock_dummy;
    688 	mbx->ops[0].read = ixgbe_read_mbx_vf_legacy;
    689 	mbx->ops[0].write = ixgbe_write_mbx_vf_legacy;
    690 	mbx->ops[0].check_for_msg = ixgbe_check_for_msg_vf;
    691 	mbx->ops[0].check_for_ack = ixgbe_check_for_ack_vf;
    692 	mbx->ops[0].check_for_rst = ixgbe_check_for_rst_vf;
    693 	mbx->ops[0].clear = NULL;
    694 
    695 	IXGBE_EVC_STORE(&mbx->stats.msgs_tx, 0);
    696 	IXGBE_EVC_STORE(&mbx->stats.msgs_rx, 0);
    697 	IXGBE_EVC_STORE(&mbx->stats.reqs, 0);
    698 	IXGBE_EVC_STORE(&mbx->stats.acks, 0);
    699 	IXGBE_EVC_STORE(&mbx->stats.rsts, 0);
    700 }
    701 
    702 /**
    703  * ixgbe_upgrade_mbx_params_vf - set initial values for vf mailbox
    704  * @hw: pointer to the HW structure
    705  *
    706  * Initializes the hw->mbx struct to correct values for vf mailbox
    707  */
    708 void ixgbe_upgrade_mbx_params_vf(struct ixgbe_hw *hw)
    709 {
    710 	struct ixgbe_mbx_info *mbx = &hw->mbx;
    711 
    712 	mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT;
    713 	mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;
    714 
    715 	mbx->size = IXGBE_VFMAILBOX_SIZE;
    716 
    717 	/* VF has only one mailbox connection, no need for more IDs */
    718 	mbx->ops[0].release = ixgbe_release_mbx_lock_vf;
    719 	mbx->ops[0].read = ixgbe_read_mbx_vf;
    720 	mbx->ops[0].write = ixgbe_write_mbx_vf;
    721 	mbx->ops[0].check_for_msg = ixgbe_check_for_msg_vf;
    722 	mbx->ops[0].check_for_ack = ixgbe_check_for_ack_vf;
    723 	mbx->ops[0].check_for_rst = ixgbe_check_for_rst_vf;
    724 	mbx->ops[0].clear = NULL;
    725 }
    726 
    727 static void ixgbe_clear_msg_pf(struct ixgbe_hw *hw, u16 vf_id)
    728 {
    729 	u32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_id);
    730 	s32 index = IXGBE_PFMBICR_INDEX(vf_id);
    731 	u32 pfmbicr;
    732 
    733 	pfmbicr = IXGBE_READ_REG(hw, IXGBE_PFMBICR(index));
    734 
    735 	if (pfmbicr & (IXGBE_PFMBICR_VFREQ_VF1 << vf_shift))
    736 		IXGBE_EVC_ADD(&hw->mbx.stats.reqs, 1);
    737 
    738 	IXGBE_WRITE_REG(hw, IXGBE_PFMBICR(index),
    739 			IXGBE_PFMBICR_VFREQ_VF1 << vf_shift);
    740 }
    741 
    742 static void ixgbe_clear_ack_pf(struct ixgbe_hw *hw, u16 vf_id)
    743 {
    744 	u32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_id);
    745 	s32 index = IXGBE_PFMBICR_INDEX(vf_id);
    746 	u32 pfmbicr;
    747 
    748 	pfmbicr = IXGBE_READ_REG(hw, IXGBE_PFMBICR(index));
    749 
    750 	if (pfmbicr & (IXGBE_PFMBICR_VFACK_VF1 << vf_shift))
    751 		IXGBE_EVC_ADD(&hw->mbx.stats.acks, 1);
    752 
    753 	IXGBE_WRITE_REG(hw, IXGBE_PFMBICR(index),
    754 			IXGBE_PFMBICR_VFACK_VF1 << vf_shift);
    755 }
    756 
    757 static s32 ixgbe_check_for_bit_pf(struct ixgbe_hw *hw, u32 mask, s32 index)
    758 {
    759 	u32 pfmbicr = IXGBE_READ_REG(hw, IXGBE_PFMBICR(index));
    760 
    761 	if (pfmbicr & mask)
    762 		return IXGBE_SUCCESS;
    763 
    764 	return IXGBE_ERR_MBX;
    765 }
    766 
    767 /**
    768  * ixgbe_check_for_msg_pf - checks to see if the VF has sent mail
    769  * @hw: pointer to the HW structure
    770  * @vf_id: the VF index
    771  *
    772  * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
    773  **/
    774 static s32 ixgbe_check_for_msg_pf(struct ixgbe_hw *hw, u16 vf_id)
    775 {
    776 	u32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_id);
    777 	s32 index = IXGBE_PFMBICR_INDEX(vf_id);
    778 
    779 	DEBUGFUNC("ixgbe_check_for_msg_pf");
    780 
    781 	if (!ixgbe_check_for_bit_pf(hw, IXGBE_PFMBICR_VFREQ_VF1 << vf_shift,
    782 				    index))
    783 		return IXGBE_SUCCESS;
    784 
    785 	return IXGBE_ERR_MBX;
    786 }
    787 
    788 /**
    789  * ixgbe_check_for_ack_pf - checks to see if the VF has ACKed
    790  * @hw: pointer to the HW structure
    791  * @vf_id: the VF index
    792  *
    793  * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
    794  **/
    795 static s32 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_id)
    796 {
    797 	u32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_id);
    798 	s32 index = IXGBE_PFMBICR_INDEX(vf_id);
    799 	s32 ret_val = IXGBE_ERR_MBX;
    800 
    801 	DEBUGFUNC("ixgbe_check_for_ack_pf");
    802 
    803 	if (!ixgbe_check_for_bit_pf(hw, IXGBE_PFMBICR_VFACK_VF1 << vf_shift,
    804 				    index)) {
    805 		ret_val = IXGBE_SUCCESS;
    806 		/* TODO: should this be autocleared? */
    807 		ixgbe_clear_ack_pf(hw, vf_id);
    808 	}
    809 
    810 	return ret_val;
    811 }
    812 
    813 /**
    814  * ixgbe_check_for_rst_pf - checks to see if the VF has reset
    815  * @hw: pointer to the HW structure
    816  * @vf_id: the VF index
    817  *
    818  * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
    819  **/
    820 static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_id)
    821 {
    822 	u32 vf_shift = IXGBE_PFVFLRE_SHIFT(vf_id);
    823 	u32 index = IXGBE_PFVFLRE_INDEX(vf_id);
    824 	s32 ret_val = IXGBE_ERR_MBX;
    825 	u32 vflre = 0;
    826 
    827 	DEBUGFUNC("ixgbe_check_for_rst_pf");
    828 
    829 	switch (hw->mac.type) {
    830 	case ixgbe_mac_82599EB:
    831 		vflre = IXGBE_READ_REG(hw, IXGBE_PFVFLRE(index));
    832 		break;
    833 	case ixgbe_mac_X550:
    834 	case ixgbe_mac_X550EM_x:
    835 	case ixgbe_mac_X550EM_a:
    836 	case ixgbe_mac_X540:
    837 		vflre = IXGBE_READ_REG(hw, IXGBE_PFVFLREC(index));
    838 		break;
    839 	default:
    840 		break;
    841 	}
    842 
    843 	if (vflre & (1 << vf_shift)) {
    844 		ret_val = IXGBE_SUCCESS;
    845 		IXGBE_WRITE_REG(hw, IXGBE_PFVFLREC(index), (1 << vf_shift));
    846 		IXGBE_EVC_ADD(&hw->mbx.stats.rsts, 1);
    847 	}
    848 
    849 	return ret_val;
    850 }
    851 
    852 /**
    853  * ixgbe_obtain_mbx_lock_pf - obtain mailbox lock
    854  * @hw: pointer to the HW structure
    855  * @vf_id: the VF index
    856  *
    857  * return SUCCESS if we obtained the mailbox lock
    858  **/
    859 static s32 ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_id)
    860 {
    861 	struct ixgbe_mbx_info *mbx = &hw->mbx;
    862 	int countdown = mbx->timeout;
    863 	s32 ret_val = IXGBE_ERR_MBX;
    864 	u32 pf_mailbox;
    865 
    866 	DEBUGFUNC("ixgbe_obtain_mbx_lock_pf");
    867 
    868 	if (!mbx->timeout)
    869 		return IXGBE_ERR_CONFIG;
    870 
    871 	while (countdown--) {
    872 		/* Reserve mailbox for PF use */
    873 		pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id));
    874 		pf_mailbox |= IXGBE_PFMAILBOX_PFU;
    875 		IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), pf_mailbox);
    876 
    877 		/* Verify that PF is the owner of the lock */
    878 		pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id));
    879 		if (pf_mailbox & IXGBE_PFMAILBOX_PFU) {
    880 			ret_val = IXGBE_SUCCESS;
    881 			break;
    882 		}
    883 
    884 		/* Wait a bit before trying again */
    885 		usec_delay(mbx->usec_delay);
    886 	}
    887 
    888 	if (ret_val != IXGBE_SUCCESS) {
    889 		ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
    890 			      "Failed to obtain mailbox lock");
    891 		ret_val = IXGBE_ERR_TIMEOUT;
    892 	}
    893 
    894 	return ret_val;
    895 }
    896 
    897 /**
    898  * ixgbe_release_mbx_lock_pf - release mailbox lock
    899  * @hw: pointer to the HW structure
    900  * @vf_id: the VF index
    901  **/
    902 static void ixgbe_release_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_id)
    903 {
    904 	u32 pf_mailbox;
    905 
    906 	DEBUGFUNC("ixgbe_release_mbx_lock_pf");
    907 
    908 	/* Return ownership of the buffer */
    909 	pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id));
    910 	pf_mailbox &= ~IXGBE_PFMAILBOX_PFU;
    911 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), pf_mailbox);
    912 }
    913 
    914 /**
    915  * ixgbe_write_mbx_pf_legacy - Places a message in the mailbox
    916  * @hw: pointer to the HW structure
    917  * @msg: The message buffer
    918  * @size: Length of buffer
    919  * @vf_id: the VF index
    920  *
    921  * returns SUCCESS if it successfully copied message into the buffer
    922  **/
    923 static s32 ixgbe_write_mbx_pf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size,
    924 				     u16 vf_id)
    925 {
    926 	s32 ret_val;
    927 	u16 i;
    928 
    929 	DEBUGFUNC("ixgbe_write_mbx_pf_legacy");
    930 
    931 	/* lock the mailbox to prevent pf/vf race condition */
    932 	ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_id);
    933 	if (ret_val)
    934 		return ret_val;
    935 
    936 	/* flush msg and acks as we are overwriting the message buffer */
    937 	ixgbe_check_for_msg_pf(hw, vf_id);
    938 	ixgbe_clear_msg_pf(hw, vf_id);
    939 	ixgbe_check_for_ack_pf(hw, vf_id);
    940 	ixgbe_clear_ack_pf(hw, vf_id);
    941 
    942 	/* copy the caller specified message to the mailbox memory buffer */
    943 	for (i = 0; i < size; i++)
    944 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i, msg[i]);
    945 
    946 	/* Interrupt VF to tell it a message has been sent and release buffer*/
    947 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), IXGBE_PFMAILBOX_STS);
    948 
    949 	/* update stats */
    950 	IXGBE_EVC_ADD(&hw->mbx.stats.msgs_tx, 1);
    951 
    952 	return IXGBE_SUCCESS;
    953 }
    954 
    955 /**
    956  * ixgbe_write_mbx_pf - Places a message in the mailbox
    957  * @hw: pointer to the HW structure
    958  * @msg: The message buffer
    959  * @size: Length of buffer
    960  * @vf_id: the VF index
    961  *
    962  * returns SUCCESS if it successfully copied message into the buffer
    963  **/
    964 static s32 ixgbe_write_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
    965 			      u16 vf_id)
    966 {
    967 	u32 pf_mailbox;
    968 	s32 ret_val;
    969 	u16 i;
    970 
    971 	DEBUGFUNC("ixgbe_write_mbx_pf");
    972 
    973 	/* lock the mailbox to prevent pf/vf race condition */
    974 	ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_id);
    975 	if (ret_val)
    976 		goto out;
    977 
    978 	/* flush msg and acks as we are overwriting the message buffer */
    979 	ixgbe_clear_msg_pf(hw, vf_id);
    980 	ixgbe_clear_ack_pf(hw, vf_id);
    981 
    982 	/* copy the caller specified message to the mailbox memory buffer */
    983 	for (i = 0; i < size; i++)
    984 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i, msg[i]);
    985 
    986 	/* Interrupt VF to tell it a message has been sent */
    987 	pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id));
    988 	pf_mailbox |= IXGBE_PFMAILBOX_STS;
    989 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), pf_mailbox);
    990 
    991 	/* if msg sent wait until we receive an ack */
    992 	ixgbe_poll_for_ack(hw, vf_id);
    993 
    994 	/* update stats */
    995 	IXGBE_EVC_ADD(&hw->mbx.stats.msgs_tx, 1);
    996 
    997 out:
    998 	hw->mbx.ops[vf_id].release(hw, vf_id);
    999 
   1000 	return ret_val;
   1001 
   1002 }
   1003 
   1004 /**
   1005  * ixgbe_read_mbx_pf_legacy - Read a message from the mailbox
   1006  * @hw: pointer to the HW structure
   1007  * @msg: The message buffer
   1008  * @size: Length of buffer
   1009  * @vf_id: the VF index
   1010  *
   1011  * This function copies a message from the mailbox buffer to the caller's
   1012  * memory buffer.  The presumption is that the caller knows that there was
   1013  * a message due to a VF request so no polling for message is needed.
   1014  **/
   1015 static s32 ixgbe_read_mbx_pf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size,
   1016 				    u16 vf_id)
   1017 {
   1018 	s32 ret_val;
   1019 	u16 i;
   1020 
   1021 	DEBUGFUNC("ixgbe_read_mbx_pf_legacy");
   1022 
   1023 	/* lock the mailbox to prevent pf/vf race condition */
   1024 	ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_id);
   1025 	if (ret_val != IXGBE_SUCCESS)
   1026 		return ret_val;
   1027 
   1028 	/* copy the message to the mailbox memory buffer */
   1029 	for (i = 0; i < size; i++)
   1030 		msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i);
   1031 
   1032 	/* Acknowledge the message and release buffer */
   1033 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), IXGBE_PFMAILBOX_ACK);
   1034 
   1035 	/* update stats */
   1036 	IXGBE_EVC_ADD(&hw->mbx.stats.msgs_rx, 1);
   1037 
   1038 	return IXGBE_SUCCESS;
   1039 }
   1040 
   1041 /**
   1042  * ixgbe_read_mbx_pf - Read a message from the mailbox
   1043  * @hw: pointer to the HW structure
   1044  * @msg: The message buffer
   1045  * @size: Length of buffer
   1046  * @vf_id: the VF index
   1047  *
   1048  * This function copies a message from the mailbox buffer to the caller's
   1049  * memory buffer.  The presumption is that the caller knows that there was
   1050  * a message due to a VF request so no polling for message is needed.
   1051  **/
   1052 static s32 ixgbe_read_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
   1053 			     u16 vf_id)
   1054 {
   1055 	u32 pf_mailbox;
   1056 	s32 ret_val;
   1057 	u16 i;
   1058 
   1059 	DEBUGFUNC("ixgbe_read_mbx_pf");
   1060 
   1061 	/* check if there is a message from VF */
   1062 	ret_val = ixgbe_check_for_msg_pf(hw, vf_id);
   1063 	if (ret_val != IXGBE_SUCCESS)
   1064 		return IXGBE_ERR_MBX_NOMSG;
   1065 
   1066 	ixgbe_clear_msg_pf(hw, vf_id);
   1067 
   1068 	/* copy the message to the mailbox memory buffer */
   1069 	for (i = 0; i < size; i++)
   1070 		msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i);
   1071 
   1072 	/* Acknowledge the message and release buffer */
   1073 	pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id));
   1074 	pf_mailbox |= IXGBE_PFMAILBOX_ACK;
   1075 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), pf_mailbox);
   1076 
   1077 	/* update stats */
   1078 	IXGBE_EVC_ADD(&hw->mbx.stats.msgs_rx, 1);
   1079 
   1080 	return IXGBE_SUCCESS;
   1081 }
   1082 
   1083 /**
   1084  * ixgbe_clear_mbx_pf - Clear Mailbox Memory
   1085  * @hw: pointer to the HW structure
   1086  * @vf_id: the VF index
   1087  *
   1088  * Set VFMBMEM of given VF to 0x0.
   1089  **/
   1090 static s32 ixgbe_clear_mbx_pf(struct ixgbe_hw *hw, u16 vf_id)
   1091 {
   1092 	u16 mbx_size = hw->mbx.size;
   1093 	u16 i;
   1094 
   1095 	if (vf_id > 63)
   1096 		return IXGBE_ERR_PARAM;
   1097 
   1098 	for (i = 0; i < mbx_size; ++i)
   1099 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i, 0x0);
   1100 
   1101 	return IXGBE_SUCCESS;
   1102 }
   1103 
   1104 /**
   1105  * ixgbe_init_mbx_params_pf_id - set initial values for pf mailbox
   1106  * @hw: pointer to the HW structure
   1107  * @vf_id: the VF index
   1108  *
   1109  * Initializes single set of the hw->mbx struct to correct values for pf mailbox
   1110  * Set of legacy functions is being used here
   1111  */
   1112 void ixgbe_init_mbx_params_pf_id(struct ixgbe_hw *hw, u16 vf_id)
   1113 {
   1114 	struct ixgbe_mbx_info *mbx = &hw->mbx;
   1115 
   1116 	mbx->ops[vf_id].release = ixgbe_release_mbx_lock_dummy;
   1117 	mbx->ops[vf_id].read = ixgbe_read_mbx_pf_legacy;
   1118 	mbx->ops[vf_id].write = ixgbe_write_mbx_pf_legacy;
   1119 	mbx->ops[vf_id].check_for_msg = ixgbe_check_for_msg_pf;
   1120 	mbx->ops[vf_id].check_for_ack = ixgbe_check_for_ack_pf;
   1121 	mbx->ops[vf_id].check_for_rst = ixgbe_check_for_rst_pf;
   1122 	mbx->ops[vf_id].clear = ixgbe_clear_mbx_pf;
   1123 }
   1124 
   1125 /**
   1126  * ixgbe_init_mbx_params_pf - set initial values for pf mailbox
   1127  * @hw: pointer to the HW structure
   1128  *
   1129  * Initializes all sets of the hw->mbx struct to correct values for pf
   1130  * mailbox. One set corresponds to single VF. It also initializes counters
   1131  * and general variables. A set of legacy functions is used by default.
   1132  */
   1133 void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw)
   1134 {
   1135 	u16 i;
   1136 	struct ixgbe_mbx_info *mbx = &hw->mbx;
   1137 
   1138 	/* Ensure we are not calling this function from VF */
   1139 	if (hw->mac.type != ixgbe_mac_82599EB &&
   1140 	    hw->mac.type != ixgbe_mac_X550 &&
   1141 	    hw->mac.type != ixgbe_mac_X550EM_x &&
   1142 	    hw->mac.type != ixgbe_mac_X550EM_a &&
   1143 	    hw->mac.type != ixgbe_mac_X540)
   1144 		return;
   1145 
   1146 	/* Initialize common mailbox settings */
   1147 	mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT;
   1148 	mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;
   1149 	mbx->size = IXGBE_VFMAILBOX_SIZE;
   1150 
   1151 	/* Initialize counters with zeroes */
   1152 	IXGBE_EVC_STORE(&mbx->stats.msgs_tx, 0);
   1153 	IXGBE_EVC_STORE(&mbx->stats.msgs_rx, 0);
   1154 	IXGBE_EVC_STORE(&mbx->stats.reqs, 0);
   1155 	IXGBE_EVC_STORE(&mbx->stats.acks, 0);
   1156 	IXGBE_EVC_STORE(&mbx->stats.rsts, 0);
   1157 
   1158 	/* No matter of VF number, we initialize params for all 64 VFs. */
   1159 	/* TODO: 1. Add a define for max VF and refactor SHARED to get rid
   1160 	 * of magic number for that (63 or 64 depending on use case.)
   1161 	 * 2. rewrite the code to dynamically allocate mbx->ops[vf_id] for
   1162 	 * certain number of VFs instead of default maximum value of 64 (0..63)
   1163 	 */
   1164 	for (i = 0; i < 64; i++)
   1165 		ixgbe_init_mbx_params_pf_id(hw, i);
   1166 }
   1167 
   1168 /**
   1169  * ixgbe_upgrade_mbx_params_pf - Upgrade initial values for pf mailbox
   1170  * @hw: pointer to the HW structure
   1171  * @vf_id: the VF index
   1172  *
   1173  * Initializes the hw->mbx struct to new function set for improved
   1174  * stability and handling of messages.
   1175  */
   1176 void ixgbe_upgrade_mbx_params_pf(struct ixgbe_hw *hw, u16 vf_id)
   1177 {
   1178 	struct ixgbe_mbx_info *mbx = &hw->mbx;
   1179 
   1180    /* Ensure we are not calling this function from VF */
   1181 	if (hw->mac.type != ixgbe_mac_82599EB &&
   1182 	    hw->mac.type != ixgbe_mac_X550 &&
   1183 	    hw->mac.type != ixgbe_mac_X550EM_x &&
   1184 	    hw->mac.type != ixgbe_mac_X550EM_a &&
   1185 	    hw->mac.type != ixgbe_mac_X540)
   1186 		return;
   1187 
   1188 	mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT;
   1189 	mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;
   1190 	mbx->size = IXGBE_VFMAILBOX_SIZE;
   1191 
   1192 	mbx->ops[vf_id].release = ixgbe_release_mbx_lock_pf;
   1193 	mbx->ops[vf_id].read = ixgbe_read_mbx_pf;
   1194 	mbx->ops[vf_id].write = ixgbe_write_mbx_pf;
   1195 	mbx->ops[vf_id].check_for_msg = ixgbe_check_for_msg_pf;
   1196 	mbx->ops[vf_id].check_for_ack = ixgbe_check_for_ack_pf;
   1197 	mbx->ops[vf_id].check_for_rst = ixgbe_check_for_rst_pf;
   1198 	mbx->ops[vf_id].clear = ixgbe_clear_mbx_pf;
   1199 }
   1200