xref: /dflybsd-src/sys/dev/netif/ix/ixgbe_mbx.c (revision 6150453f26f6ee01b60ce647b20bc8afcfc71c8e)
179251f5eSSepherosa Ziehau /******************************************************************************
279251f5eSSepherosa Ziehau 
3*6150453fSSepherosa Ziehau   Copyright (c) 2001-2017, Intel Corporation
479251f5eSSepherosa Ziehau   All rights reserved.
579251f5eSSepherosa Ziehau 
679251f5eSSepherosa Ziehau   Redistribution and use in source and binary forms, with or without
779251f5eSSepherosa Ziehau   modification, are permitted provided that the following conditions are met:
879251f5eSSepherosa Ziehau 
979251f5eSSepherosa Ziehau    1. Redistributions of source code must retain the above copyright notice,
1079251f5eSSepherosa Ziehau       this list of conditions and the following disclaimer.
1179251f5eSSepherosa Ziehau 
1279251f5eSSepherosa Ziehau    2. Redistributions in binary form must reproduce the above copyright
1379251f5eSSepherosa Ziehau       notice, this list of conditions and the following disclaimer in the
1479251f5eSSepherosa Ziehau       documentation and/or other materials provided with the distribution.
1579251f5eSSepherosa Ziehau 
1679251f5eSSepherosa Ziehau    3. Neither the name of the Intel Corporation nor the names of its
1779251f5eSSepherosa Ziehau       contributors may be used to endorse or promote products derived from
1879251f5eSSepherosa Ziehau       this software without specific prior written permission.
1979251f5eSSepherosa Ziehau 
2079251f5eSSepherosa Ziehau   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2179251f5eSSepherosa Ziehau   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2279251f5eSSepherosa Ziehau   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2379251f5eSSepherosa Ziehau   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
2479251f5eSSepherosa Ziehau   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2579251f5eSSepherosa Ziehau   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2679251f5eSSepherosa Ziehau   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2779251f5eSSepherosa Ziehau   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2879251f5eSSepherosa Ziehau   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2979251f5eSSepherosa Ziehau   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3079251f5eSSepherosa Ziehau   POSSIBILITY OF SUCH DAMAGE.
3179251f5eSSepherosa Ziehau 
3279251f5eSSepherosa Ziehau ******************************************************************************/
3379251f5eSSepherosa Ziehau /*$FreeBSD$*/
3479251f5eSSepherosa Ziehau 
3579251f5eSSepherosa Ziehau #include "ixgbe_type.h"
3679251f5eSSepherosa Ziehau #include "ixgbe_mbx.h"
3779251f5eSSepherosa Ziehau 
3879251f5eSSepherosa Ziehau /**
3979251f5eSSepherosa Ziehau  *  ixgbe_read_mbx - Reads a message from the mailbox
4079251f5eSSepherosa Ziehau  *  @hw: pointer to the HW structure
4179251f5eSSepherosa Ziehau  *  @msg: The message buffer
4279251f5eSSepherosa Ziehau  *  @size: Length of buffer
4379251f5eSSepherosa Ziehau  *  @mbx_id: id of mailbox to read
4479251f5eSSepherosa Ziehau  *
4579251f5eSSepherosa Ziehau  *  returns SUCCESS if it successfuly read message from buffer
4679251f5eSSepherosa Ziehau  **/
ixgbe_read_mbx(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 mbx_id)4779251f5eSSepherosa Ziehau s32 ixgbe_read_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
4879251f5eSSepherosa Ziehau {
4979251f5eSSepherosa Ziehau 	struct ixgbe_mbx_info *mbx = &hw->mbx;
5079251f5eSSepherosa Ziehau 	s32 ret_val = IXGBE_ERR_MBX;
5179251f5eSSepherosa Ziehau 
5279251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_read_mbx");
5379251f5eSSepherosa Ziehau 
5479251f5eSSepherosa Ziehau 	/* limit read to size of mailbox */
5579251f5eSSepherosa Ziehau 	if (size > mbx->size)
5679251f5eSSepherosa Ziehau 		size = mbx->size;
5779251f5eSSepherosa Ziehau 
5879251f5eSSepherosa Ziehau 	if (mbx->ops.read)
5979251f5eSSepherosa Ziehau 		ret_val = mbx->ops.read(hw, msg, size, mbx_id);
6079251f5eSSepherosa Ziehau 
6179251f5eSSepherosa Ziehau 	return ret_val;
6279251f5eSSepherosa Ziehau }
6379251f5eSSepherosa Ziehau 
6479251f5eSSepherosa Ziehau /**
6579251f5eSSepherosa Ziehau  *  ixgbe_write_mbx - Write a message to the mailbox
6679251f5eSSepherosa Ziehau  *  @hw: pointer to the HW structure
6779251f5eSSepherosa Ziehau  *  @msg: The message buffer
6879251f5eSSepherosa Ziehau  *  @size: Length of buffer
6979251f5eSSepherosa Ziehau  *  @mbx_id: id of mailbox to write
7079251f5eSSepherosa Ziehau  *
7179251f5eSSepherosa Ziehau  *  returns SUCCESS if it successfully copied message into the buffer
7279251f5eSSepherosa Ziehau  **/
ixgbe_write_mbx(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 mbx_id)7379251f5eSSepherosa Ziehau s32 ixgbe_write_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
7479251f5eSSepherosa Ziehau {
7579251f5eSSepherosa Ziehau 	struct ixgbe_mbx_info *mbx = &hw->mbx;
7679251f5eSSepherosa Ziehau 	s32 ret_val = IXGBE_SUCCESS;
7779251f5eSSepherosa Ziehau 
7879251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_write_mbx");
7979251f5eSSepherosa Ziehau 
8079251f5eSSepherosa Ziehau 	if (size > mbx->size) {
8179251f5eSSepherosa Ziehau 		ret_val = IXGBE_ERR_MBX;
8279251f5eSSepherosa Ziehau 		ERROR_REPORT2(IXGBE_ERROR_ARGUMENT,
8379251f5eSSepherosa Ziehau 			     "Invalid mailbox message size %d", size);
8479251f5eSSepherosa Ziehau 	} else if (mbx->ops.write)
8579251f5eSSepherosa Ziehau 		ret_val = mbx->ops.write(hw, msg, size, mbx_id);
8679251f5eSSepherosa Ziehau 
8779251f5eSSepherosa Ziehau 	return ret_val;
8879251f5eSSepherosa Ziehau }
8979251f5eSSepherosa Ziehau 
9079251f5eSSepherosa Ziehau /**
9179251f5eSSepherosa Ziehau  *  ixgbe_check_for_msg - checks to see if someone sent us mail
9279251f5eSSepherosa Ziehau  *  @hw: pointer to the HW structure
9379251f5eSSepherosa Ziehau  *  @mbx_id: id of mailbox to check
9479251f5eSSepherosa Ziehau  *
9579251f5eSSepherosa Ziehau  *  returns SUCCESS if the Status bit was found or else ERR_MBX
9679251f5eSSepherosa Ziehau  **/
ixgbe_check_for_msg(struct ixgbe_hw * hw,u16 mbx_id)9779251f5eSSepherosa Ziehau s32 ixgbe_check_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
9879251f5eSSepherosa Ziehau {
9979251f5eSSepherosa Ziehau 	struct ixgbe_mbx_info *mbx = &hw->mbx;
10079251f5eSSepherosa Ziehau 	s32 ret_val = IXGBE_ERR_MBX;
10179251f5eSSepherosa Ziehau 
10279251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_check_for_msg");
10379251f5eSSepherosa Ziehau 
10479251f5eSSepherosa Ziehau 	if (mbx->ops.check_for_msg)
10579251f5eSSepherosa Ziehau 		ret_val = mbx->ops.check_for_msg(hw, mbx_id);
10679251f5eSSepherosa Ziehau 
10779251f5eSSepherosa Ziehau 	return ret_val;
10879251f5eSSepherosa Ziehau }
10979251f5eSSepherosa Ziehau 
11079251f5eSSepherosa Ziehau /**
11179251f5eSSepherosa Ziehau  *  ixgbe_check_for_ack - checks to see if someone sent us ACK
11279251f5eSSepherosa Ziehau  *  @hw: pointer to the HW structure
11379251f5eSSepherosa Ziehau  *  @mbx_id: id of mailbox to check
11479251f5eSSepherosa Ziehau  *
11579251f5eSSepherosa Ziehau  *  returns SUCCESS if the Status bit was found or else ERR_MBX
11679251f5eSSepherosa Ziehau  **/
ixgbe_check_for_ack(struct ixgbe_hw * hw,u16 mbx_id)11779251f5eSSepherosa Ziehau s32 ixgbe_check_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
11879251f5eSSepherosa Ziehau {
11979251f5eSSepherosa Ziehau 	struct ixgbe_mbx_info *mbx = &hw->mbx;
12079251f5eSSepherosa Ziehau 	s32 ret_val = IXGBE_ERR_MBX;
12179251f5eSSepherosa Ziehau 
12279251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_check_for_ack");
12379251f5eSSepherosa Ziehau 
12479251f5eSSepherosa Ziehau 	if (mbx->ops.check_for_ack)
12579251f5eSSepherosa Ziehau 		ret_val = mbx->ops.check_for_ack(hw, mbx_id);
12679251f5eSSepherosa Ziehau 
12779251f5eSSepherosa Ziehau 	return ret_val;
12879251f5eSSepherosa Ziehau }
12979251f5eSSepherosa Ziehau 
13079251f5eSSepherosa Ziehau /**
13179251f5eSSepherosa Ziehau  *  ixgbe_check_for_rst - checks to see if other side has reset
13279251f5eSSepherosa Ziehau  *  @hw: pointer to the HW structure
13379251f5eSSepherosa Ziehau  *  @mbx_id: id of mailbox to check
13479251f5eSSepherosa Ziehau  *
13579251f5eSSepherosa Ziehau  *  returns SUCCESS if the Status bit was found or else ERR_MBX
13679251f5eSSepherosa Ziehau  **/
ixgbe_check_for_rst(struct ixgbe_hw * hw,u16 mbx_id)13779251f5eSSepherosa Ziehau s32 ixgbe_check_for_rst(struct ixgbe_hw *hw, u16 mbx_id)
13879251f5eSSepherosa Ziehau {
13979251f5eSSepherosa Ziehau 	struct ixgbe_mbx_info *mbx = &hw->mbx;
14079251f5eSSepherosa Ziehau 	s32 ret_val = IXGBE_ERR_MBX;
14179251f5eSSepherosa Ziehau 
14279251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_check_for_rst");
14379251f5eSSepherosa Ziehau 
14479251f5eSSepherosa Ziehau 	if (mbx->ops.check_for_rst)
14579251f5eSSepherosa Ziehau 		ret_val = mbx->ops.check_for_rst(hw, mbx_id);
14679251f5eSSepherosa Ziehau 
14779251f5eSSepherosa Ziehau 	return ret_val;
14879251f5eSSepherosa Ziehau }
14979251f5eSSepherosa Ziehau 
15079251f5eSSepherosa Ziehau /**
15179251f5eSSepherosa Ziehau  *  ixgbe_poll_for_msg - Wait for message notification
15279251f5eSSepherosa Ziehau  *  @hw: pointer to the HW structure
15379251f5eSSepherosa Ziehau  *  @mbx_id: id of mailbox to write
15479251f5eSSepherosa Ziehau  *
15579251f5eSSepherosa Ziehau  *  returns SUCCESS if it successfully received a message notification
15679251f5eSSepherosa Ziehau  **/
ixgbe_poll_for_msg(struct ixgbe_hw * hw,u16 mbx_id)15779251f5eSSepherosa Ziehau static s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
15879251f5eSSepherosa Ziehau {
15979251f5eSSepherosa Ziehau 	struct ixgbe_mbx_info *mbx = &hw->mbx;
16079251f5eSSepherosa Ziehau 	int countdown = mbx->timeout;
16179251f5eSSepherosa Ziehau 
16279251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_poll_for_msg");
16379251f5eSSepherosa Ziehau 
16479251f5eSSepherosa Ziehau 	if (!countdown || !mbx->ops.check_for_msg)
16579251f5eSSepherosa Ziehau 		goto out;
16679251f5eSSepherosa Ziehau 
16779251f5eSSepherosa Ziehau 	while (countdown && mbx->ops.check_for_msg(hw, mbx_id)) {
16879251f5eSSepherosa Ziehau 		countdown--;
16979251f5eSSepherosa Ziehau 		if (!countdown)
17079251f5eSSepherosa Ziehau 			break;
17179251f5eSSepherosa Ziehau 		usec_delay(mbx->usec_delay);
17279251f5eSSepherosa Ziehau 	}
17379251f5eSSepherosa Ziehau 
17479251f5eSSepherosa Ziehau 	if (countdown == 0)
17579251f5eSSepherosa Ziehau 		ERROR_REPORT2(IXGBE_ERROR_POLLING,
17679251f5eSSepherosa Ziehau 			   "Polling for VF%d mailbox message timedout", mbx_id);
17779251f5eSSepherosa Ziehau 
17879251f5eSSepherosa Ziehau out:
17979251f5eSSepherosa Ziehau 	return countdown ? IXGBE_SUCCESS : IXGBE_ERR_MBX;
18079251f5eSSepherosa Ziehau }
18179251f5eSSepherosa Ziehau 
18279251f5eSSepherosa Ziehau /**
18379251f5eSSepherosa Ziehau  *  ixgbe_poll_for_ack - Wait for message acknowledgement
18479251f5eSSepherosa Ziehau  *  @hw: pointer to the HW structure
18579251f5eSSepherosa Ziehau  *  @mbx_id: id of mailbox to write
18679251f5eSSepherosa Ziehau  *
18779251f5eSSepherosa Ziehau  *  returns SUCCESS if it successfully received a message acknowledgement
18879251f5eSSepherosa Ziehau  **/
ixgbe_poll_for_ack(struct ixgbe_hw * hw,u16 mbx_id)18979251f5eSSepherosa Ziehau static s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
19079251f5eSSepherosa Ziehau {
19179251f5eSSepherosa Ziehau 	struct ixgbe_mbx_info *mbx = &hw->mbx;
19279251f5eSSepherosa Ziehau 	int countdown = mbx->timeout;
19379251f5eSSepherosa Ziehau 
19479251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_poll_for_ack");
19579251f5eSSepherosa Ziehau 
19679251f5eSSepherosa Ziehau 	if (!countdown || !mbx->ops.check_for_ack)
19779251f5eSSepherosa Ziehau 		goto out;
19879251f5eSSepherosa Ziehau 
19979251f5eSSepherosa Ziehau 	while (countdown && mbx->ops.check_for_ack(hw, mbx_id)) {
20079251f5eSSepherosa Ziehau 		countdown--;
20179251f5eSSepherosa Ziehau 		if (!countdown)
20279251f5eSSepherosa Ziehau 			break;
20379251f5eSSepherosa Ziehau 		usec_delay(mbx->usec_delay);
20479251f5eSSepherosa Ziehau 	}
20579251f5eSSepherosa Ziehau 
20679251f5eSSepherosa Ziehau 	if (countdown == 0)
20779251f5eSSepherosa Ziehau 		ERROR_REPORT2(IXGBE_ERROR_POLLING,
20879251f5eSSepherosa Ziehau 			     "Polling for VF%d mailbox ack timedout", mbx_id);
20979251f5eSSepherosa Ziehau 
21079251f5eSSepherosa Ziehau out:
21179251f5eSSepherosa Ziehau 	return countdown ? IXGBE_SUCCESS : IXGBE_ERR_MBX;
21279251f5eSSepherosa Ziehau }
21379251f5eSSepherosa Ziehau 
21479251f5eSSepherosa Ziehau /**
21579251f5eSSepherosa Ziehau  *  ixgbe_read_posted_mbx - Wait for message notification and receive message
21679251f5eSSepherosa Ziehau  *  @hw: pointer to the HW structure
21779251f5eSSepherosa Ziehau  *  @msg: The message buffer
21879251f5eSSepherosa Ziehau  *  @size: Length of buffer
21979251f5eSSepherosa Ziehau  *  @mbx_id: id of mailbox to write
22079251f5eSSepherosa Ziehau  *
22179251f5eSSepherosa Ziehau  *  returns SUCCESS if it successfully received a message notification and
22279251f5eSSepherosa Ziehau  *  copied it into the receive buffer.
22379251f5eSSepherosa Ziehau  **/
ixgbe_read_posted_mbx(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 mbx_id)22479251f5eSSepherosa Ziehau s32 ixgbe_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
22579251f5eSSepherosa Ziehau {
22679251f5eSSepherosa Ziehau 	struct ixgbe_mbx_info *mbx = &hw->mbx;
22779251f5eSSepherosa Ziehau 	s32 ret_val = IXGBE_ERR_MBX;
22879251f5eSSepherosa Ziehau 
22979251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_read_posted_mbx");
23079251f5eSSepherosa Ziehau 
23179251f5eSSepherosa Ziehau 	if (!mbx->ops.read)
23279251f5eSSepherosa Ziehau 		goto out;
23379251f5eSSepherosa Ziehau 
23479251f5eSSepherosa Ziehau 	ret_val = ixgbe_poll_for_msg(hw, mbx_id);
23579251f5eSSepherosa Ziehau 
23679251f5eSSepherosa Ziehau 	/* if ack received read message, otherwise we timed out */
23779251f5eSSepherosa Ziehau 	if (!ret_val)
23879251f5eSSepherosa Ziehau 		ret_val = mbx->ops.read(hw, msg, size, mbx_id);
23979251f5eSSepherosa Ziehau out:
24079251f5eSSepherosa Ziehau 	return ret_val;
24179251f5eSSepherosa Ziehau }
24279251f5eSSepherosa Ziehau 
24379251f5eSSepherosa Ziehau /**
24479251f5eSSepherosa Ziehau  *  ixgbe_write_posted_mbx - Write a message to the mailbox, wait for ack
24579251f5eSSepherosa Ziehau  *  @hw: pointer to the HW structure
24679251f5eSSepherosa Ziehau  *  @msg: The message buffer
24779251f5eSSepherosa Ziehau  *  @size: Length of buffer
24879251f5eSSepherosa Ziehau  *  @mbx_id: id of mailbox to write
24979251f5eSSepherosa Ziehau  *
25079251f5eSSepherosa Ziehau  *  returns SUCCESS if it successfully copied message into the buffer and
25179251f5eSSepherosa Ziehau  *  received an ack to that message within delay * timeout period
25279251f5eSSepherosa Ziehau  **/
ixgbe_write_posted_mbx(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 mbx_id)25379251f5eSSepherosa Ziehau s32 ixgbe_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size,
25479251f5eSSepherosa Ziehau 			   u16 mbx_id)
25579251f5eSSepherosa Ziehau {
25679251f5eSSepherosa Ziehau 	struct ixgbe_mbx_info *mbx = &hw->mbx;
25779251f5eSSepherosa Ziehau 	s32 ret_val = IXGBE_ERR_MBX;
25879251f5eSSepherosa Ziehau 
25979251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_write_posted_mbx");
26079251f5eSSepherosa Ziehau 
26179251f5eSSepherosa Ziehau 	/* exit if either we can't write or there isn't a defined timeout */
26279251f5eSSepherosa Ziehau 	if (!mbx->ops.write || !mbx->timeout)
26379251f5eSSepherosa Ziehau 		goto out;
26479251f5eSSepherosa Ziehau 
26579251f5eSSepherosa Ziehau 	/* send msg */
26679251f5eSSepherosa Ziehau 	ret_val = mbx->ops.write(hw, msg, size, mbx_id);
26779251f5eSSepherosa Ziehau 
26879251f5eSSepherosa Ziehau 	/* if msg sent wait until we receive an ack */
26979251f5eSSepherosa Ziehau 	if (!ret_val)
27079251f5eSSepherosa Ziehau 		ret_val = ixgbe_poll_for_ack(hw, mbx_id);
27179251f5eSSepherosa Ziehau out:
27279251f5eSSepherosa Ziehau 	return ret_val;
27379251f5eSSepherosa Ziehau }
27479251f5eSSepherosa Ziehau 
27579251f5eSSepherosa Ziehau /**
27679251f5eSSepherosa Ziehau  *  ixgbe_init_mbx_ops_generic - Initialize MB function pointers
27779251f5eSSepherosa Ziehau  *  @hw: pointer to the HW structure
27879251f5eSSepherosa Ziehau  *
27979251f5eSSepherosa Ziehau  *  Setups up the mailbox read and write message function pointers
28079251f5eSSepherosa Ziehau  **/
ixgbe_init_mbx_ops_generic(struct ixgbe_hw * hw)28179251f5eSSepherosa Ziehau void ixgbe_init_mbx_ops_generic(struct ixgbe_hw *hw)
28279251f5eSSepherosa Ziehau {
28379251f5eSSepherosa Ziehau 	struct ixgbe_mbx_info *mbx = &hw->mbx;
28479251f5eSSepherosa Ziehau 
28579251f5eSSepherosa Ziehau 	mbx->ops.read_posted = ixgbe_read_posted_mbx;
28679251f5eSSepherosa Ziehau 	mbx->ops.write_posted = ixgbe_write_posted_mbx;
28779251f5eSSepherosa Ziehau }
28879251f5eSSepherosa Ziehau 
28979251f5eSSepherosa Ziehau /**
29079251f5eSSepherosa Ziehau  *  ixgbe_read_v2p_mailbox - read v2p mailbox
29179251f5eSSepherosa Ziehau  *  @hw: pointer to the HW structure
29279251f5eSSepherosa Ziehau  *
29379251f5eSSepherosa Ziehau  *  This function is used to read the v2p mailbox without losing the read to
29479251f5eSSepherosa Ziehau  *  clear status bits.
29579251f5eSSepherosa Ziehau  **/
ixgbe_read_v2p_mailbox(struct ixgbe_hw * hw)29679251f5eSSepherosa Ziehau static u32 ixgbe_read_v2p_mailbox(struct ixgbe_hw *hw)
29779251f5eSSepherosa Ziehau {
29879251f5eSSepherosa Ziehau 	u32 v2p_mailbox = IXGBE_READ_REG(hw, IXGBE_VFMAILBOX);
29979251f5eSSepherosa Ziehau 
30079251f5eSSepherosa Ziehau 	v2p_mailbox |= hw->mbx.v2p_mailbox;
30179251f5eSSepherosa Ziehau 	hw->mbx.v2p_mailbox |= v2p_mailbox & IXGBE_VFMAILBOX_R2C_BITS;
30279251f5eSSepherosa Ziehau 
30379251f5eSSepherosa Ziehau 	return v2p_mailbox;
30479251f5eSSepherosa Ziehau }
30579251f5eSSepherosa Ziehau 
30679251f5eSSepherosa Ziehau /**
30779251f5eSSepherosa Ziehau  *  ixgbe_check_for_bit_vf - Determine if a status bit was set
30879251f5eSSepherosa Ziehau  *  @hw: pointer to the HW structure
30979251f5eSSepherosa Ziehau  *  @mask: bitmask for bits to be tested and cleared
31079251f5eSSepherosa Ziehau  *
31179251f5eSSepherosa Ziehau  *  This function is used to check for the read to clear bits within
31279251f5eSSepherosa Ziehau  *  the V2P mailbox.
31379251f5eSSepherosa Ziehau  **/
ixgbe_check_for_bit_vf(struct ixgbe_hw * hw,u32 mask)31479251f5eSSepherosa Ziehau static s32 ixgbe_check_for_bit_vf(struct ixgbe_hw *hw, u32 mask)
31579251f5eSSepherosa Ziehau {
31679251f5eSSepherosa Ziehau 	u32 v2p_mailbox = ixgbe_read_v2p_mailbox(hw);
31779251f5eSSepherosa Ziehau 	s32 ret_val = IXGBE_ERR_MBX;
31879251f5eSSepherosa Ziehau 
31979251f5eSSepherosa Ziehau 	if (v2p_mailbox & mask)
32079251f5eSSepherosa Ziehau 		ret_val = IXGBE_SUCCESS;
32179251f5eSSepherosa Ziehau 
32279251f5eSSepherosa Ziehau 	hw->mbx.v2p_mailbox &= ~mask;
32379251f5eSSepherosa Ziehau 
32479251f5eSSepherosa Ziehau 	return ret_val;
32579251f5eSSepherosa Ziehau }
32679251f5eSSepherosa Ziehau 
32779251f5eSSepherosa Ziehau /**
32879251f5eSSepherosa Ziehau  *  ixgbe_check_for_msg_vf - checks to see if the PF has sent mail
32979251f5eSSepherosa Ziehau  *  @hw: pointer to the HW structure
33079251f5eSSepherosa Ziehau  *  @mbx_id: id of mailbox to check
33179251f5eSSepherosa Ziehau  *
33279251f5eSSepherosa Ziehau  *  returns SUCCESS if the PF has set the Status bit or else ERR_MBX
33379251f5eSSepherosa Ziehau  **/
ixgbe_check_for_msg_vf(struct ixgbe_hw * hw,u16 mbx_id)33479251f5eSSepherosa Ziehau static s32 ixgbe_check_for_msg_vf(struct ixgbe_hw *hw, u16 mbx_id)
33579251f5eSSepherosa Ziehau {
33679251f5eSSepherosa Ziehau 	s32 ret_val = IXGBE_ERR_MBX;
33779251f5eSSepherosa Ziehau 
33879251f5eSSepherosa Ziehau 	UNREFERENCED_1PARAMETER(mbx_id);
33979251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_check_for_msg_vf");
34079251f5eSSepherosa Ziehau 
34179251f5eSSepherosa Ziehau 	if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFSTS)) {
34279251f5eSSepherosa Ziehau 		ret_val = IXGBE_SUCCESS;
34379251f5eSSepherosa Ziehau 		hw->mbx.stats.reqs++;
34479251f5eSSepherosa Ziehau 	}
34579251f5eSSepherosa Ziehau 
34679251f5eSSepherosa Ziehau 	return ret_val;
34779251f5eSSepherosa Ziehau }
34879251f5eSSepherosa Ziehau 
34979251f5eSSepherosa Ziehau /**
35079251f5eSSepherosa Ziehau  *  ixgbe_check_for_ack_vf - checks to see if the PF has ACK'd
35179251f5eSSepherosa Ziehau  *  @hw: pointer to the HW structure
35279251f5eSSepherosa Ziehau  *  @mbx_id: id of mailbox to check
35379251f5eSSepherosa Ziehau  *
35479251f5eSSepherosa Ziehau  *  returns SUCCESS if the PF has set the ACK bit or else ERR_MBX
35579251f5eSSepherosa Ziehau  **/
ixgbe_check_for_ack_vf(struct ixgbe_hw * hw,u16 mbx_id)35679251f5eSSepherosa Ziehau static s32 ixgbe_check_for_ack_vf(struct ixgbe_hw *hw, u16 mbx_id)
35779251f5eSSepherosa Ziehau {
35879251f5eSSepherosa Ziehau 	s32 ret_val = IXGBE_ERR_MBX;
35979251f5eSSepherosa Ziehau 
36079251f5eSSepherosa Ziehau 	UNREFERENCED_1PARAMETER(mbx_id);
36179251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_check_for_ack_vf");
36279251f5eSSepherosa Ziehau 
36379251f5eSSepherosa Ziehau 	if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFACK)) {
36479251f5eSSepherosa Ziehau 		ret_val = IXGBE_SUCCESS;
36579251f5eSSepherosa Ziehau 		hw->mbx.stats.acks++;
36679251f5eSSepherosa Ziehau 	}
36779251f5eSSepherosa Ziehau 
36879251f5eSSepherosa Ziehau 	return ret_val;
36979251f5eSSepherosa Ziehau }
37079251f5eSSepherosa Ziehau 
37179251f5eSSepherosa Ziehau /**
37279251f5eSSepherosa Ziehau  *  ixgbe_check_for_rst_vf - checks to see if the PF has reset
37379251f5eSSepherosa Ziehau  *  @hw: pointer to the HW structure
37479251f5eSSepherosa Ziehau  *  @mbx_id: id of mailbox to check
37579251f5eSSepherosa Ziehau  *
37679251f5eSSepherosa Ziehau  *  returns TRUE if the PF has set the reset done bit or else FALSE
37779251f5eSSepherosa Ziehau  **/
ixgbe_check_for_rst_vf(struct ixgbe_hw * hw,u16 mbx_id)37879251f5eSSepherosa Ziehau static s32 ixgbe_check_for_rst_vf(struct ixgbe_hw *hw, u16 mbx_id)
37979251f5eSSepherosa Ziehau {
38079251f5eSSepherosa Ziehau 	s32 ret_val = IXGBE_ERR_MBX;
38179251f5eSSepherosa Ziehau 
38279251f5eSSepherosa Ziehau 	UNREFERENCED_1PARAMETER(mbx_id);
38379251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_check_for_rst_vf");
38479251f5eSSepherosa Ziehau 
38579251f5eSSepherosa Ziehau 	if (!ixgbe_check_for_bit_vf(hw, (IXGBE_VFMAILBOX_RSTD |
38679251f5eSSepherosa Ziehau 	    IXGBE_VFMAILBOX_RSTI))) {
38779251f5eSSepherosa Ziehau 		ret_val = IXGBE_SUCCESS;
38879251f5eSSepherosa Ziehau 		hw->mbx.stats.rsts++;
38979251f5eSSepherosa Ziehau 	}
39079251f5eSSepherosa Ziehau 
39179251f5eSSepherosa Ziehau 	return ret_val;
39279251f5eSSepherosa Ziehau }
39379251f5eSSepherosa Ziehau 
39479251f5eSSepherosa Ziehau /**
39579251f5eSSepherosa Ziehau  *  ixgbe_obtain_mbx_lock_vf - obtain mailbox lock
39679251f5eSSepherosa Ziehau  *  @hw: pointer to the HW structure
39779251f5eSSepherosa Ziehau  *
39879251f5eSSepherosa Ziehau  *  return SUCCESS if we obtained the mailbox lock
39979251f5eSSepherosa Ziehau  **/
ixgbe_obtain_mbx_lock_vf(struct ixgbe_hw * hw)40079251f5eSSepherosa Ziehau static s32 ixgbe_obtain_mbx_lock_vf(struct ixgbe_hw *hw)
40179251f5eSSepherosa Ziehau {
40279251f5eSSepherosa Ziehau 	s32 ret_val = IXGBE_ERR_MBX;
40379251f5eSSepherosa Ziehau 
40479251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_obtain_mbx_lock_vf");
40579251f5eSSepherosa Ziehau 
40679251f5eSSepherosa Ziehau 	/* Take ownership of the buffer */
40779251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_VFU);
40879251f5eSSepherosa Ziehau 
40979251f5eSSepherosa Ziehau 	/* reserve mailbox for vf use */
41079251f5eSSepherosa Ziehau 	if (ixgbe_read_v2p_mailbox(hw) & IXGBE_VFMAILBOX_VFU)
41179251f5eSSepherosa Ziehau 		ret_val = IXGBE_SUCCESS;
41279251f5eSSepherosa Ziehau 
41379251f5eSSepherosa Ziehau 	return ret_val;
41479251f5eSSepherosa Ziehau }
41579251f5eSSepherosa Ziehau 
41679251f5eSSepherosa Ziehau /**
41779251f5eSSepherosa Ziehau  *  ixgbe_write_mbx_vf - Write a message to the mailbox
41879251f5eSSepherosa Ziehau  *  @hw: pointer to the HW structure
41979251f5eSSepherosa Ziehau  *  @msg: The message buffer
42079251f5eSSepherosa Ziehau  *  @size: Length of buffer
42179251f5eSSepherosa Ziehau  *  @mbx_id: id of mailbox to write
42279251f5eSSepherosa Ziehau  *
42379251f5eSSepherosa Ziehau  *  returns SUCCESS if it successfully copied message into the buffer
42479251f5eSSepherosa Ziehau  **/
ixgbe_write_mbx_vf(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 mbx_id)42579251f5eSSepherosa Ziehau static s32 ixgbe_write_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,
42679251f5eSSepherosa Ziehau 			      u16 mbx_id)
42779251f5eSSepherosa Ziehau {
42879251f5eSSepherosa Ziehau 	s32 ret_val;
42979251f5eSSepherosa Ziehau 	u16 i;
43079251f5eSSepherosa Ziehau 
43179251f5eSSepherosa Ziehau 	UNREFERENCED_1PARAMETER(mbx_id);
43279251f5eSSepherosa Ziehau 
43379251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_write_mbx_vf");
43479251f5eSSepherosa Ziehau 
43579251f5eSSepherosa Ziehau 	/* lock the mailbox to prevent pf/vf race condition */
43679251f5eSSepherosa Ziehau 	ret_val = ixgbe_obtain_mbx_lock_vf(hw);
43779251f5eSSepherosa Ziehau 	if (ret_val)
43879251f5eSSepherosa Ziehau 		goto out_no_write;
43979251f5eSSepherosa Ziehau 
44079251f5eSSepherosa Ziehau 	/* flush msg and acks as we are overwriting the message buffer */
44179251f5eSSepherosa Ziehau 	ixgbe_check_for_msg_vf(hw, 0);
44279251f5eSSepherosa Ziehau 	ixgbe_check_for_ack_vf(hw, 0);
44379251f5eSSepherosa Ziehau 
44479251f5eSSepherosa Ziehau 	/* copy the caller specified message to the mailbox memory buffer */
44579251f5eSSepherosa Ziehau 	for (i = 0; i < size; i++)
44679251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFMBMEM, i, msg[i]);
44779251f5eSSepherosa Ziehau 
44879251f5eSSepherosa Ziehau 	/* update stats */
44979251f5eSSepherosa Ziehau 	hw->mbx.stats.msgs_tx++;
45079251f5eSSepherosa Ziehau 
45179251f5eSSepherosa Ziehau 	/* Drop VFU and interrupt the PF to tell it a message has been sent */
45279251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_REQ);
45379251f5eSSepherosa Ziehau 
45479251f5eSSepherosa Ziehau out_no_write:
45579251f5eSSepherosa Ziehau 	return ret_val;
45679251f5eSSepherosa Ziehau }
45779251f5eSSepherosa Ziehau 
45879251f5eSSepherosa Ziehau /**
45979251f5eSSepherosa Ziehau  *  ixgbe_read_mbx_vf - Reads a message from the inbox intended for vf
46079251f5eSSepherosa Ziehau  *  @hw: pointer to the HW structure
46179251f5eSSepherosa Ziehau  *  @msg: The message buffer
46279251f5eSSepherosa Ziehau  *  @size: Length of buffer
46379251f5eSSepherosa Ziehau  *  @mbx_id: id of mailbox to read
46479251f5eSSepherosa Ziehau  *
46579251f5eSSepherosa Ziehau  *  returns SUCCESS if it successfuly read message from buffer
46679251f5eSSepherosa Ziehau  **/
ixgbe_read_mbx_vf(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 mbx_id)46779251f5eSSepherosa Ziehau static s32 ixgbe_read_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,
46879251f5eSSepherosa Ziehau 			     u16 mbx_id)
46979251f5eSSepherosa Ziehau {
47079251f5eSSepherosa Ziehau 	s32 ret_val = IXGBE_SUCCESS;
47179251f5eSSepherosa Ziehau 	u16 i;
47279251f5eSSepherosa Ziehau 
47379251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_read_mbx_vf");
47479251f5eSSepherosa Ziehau 	UNREFERENCED_1PARAMETER(mbx_id);
47579251f5eSSepherosa Ziehau 
47679251f5eSSepherosa Ziehau 	/* lock the mailbox to prevent pf/vf race condition */
47779251f5eSSepherosa Ziehau 	ret_val = ixgbe_obtain_mbx_lock_vf(hw);
47879251f5eSSepherosa Ziehau 	if (ret_val)
47979251f5eSSepherosa Ziehau 		goto out_no_read;
48079251f5eSSepherosa Ziehau 
48179251f5eSSepherosa Ziehau 	/* copy the message from the mailbox memory buffer */
48279251f5eSSepherosa Ziehau 	for (i = 0; i < size; i++)
48379251f5eSSepherosa Ziehau 		msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i);
48479251f5eSSepherosa Ziehau 
48579251f5eSSepherosa Ziehau 	/* Acknowledge receipt and release mailbox, then we're done */
48679251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_ACK);
48779251f5eSSepherosa Ziehau 
48879251f5eSSepherosa Ziehau 	/* update stats */
48979251f5eSSepherosa Ziehau 	hw->mbx.stats.msgs_rx++;
49079251f5eSSepherosa Ziehau 
49179251f5eSSepherosa Ziehau out_no_read:
49279251f5eSSepherosa Ziehau 	return ret_val;
49379251f5eSSepherosa Ziehau }
49479251f5eSSepherosa Ziehau 
49579251f5eSSepherosa Ziehau /**
49679251f5eSSepherosa Ziehau  *  ixgbe_init_mbx_params_vf - set initial values for vf mailbox
49779251f5eSSepherosa Ziehau  *  @hw: pointer to the HW structure
49879251f5eSSepherosa Ziehau  *
49979251f5eSSepherosa Ziehau  *  Initializes the hw->mbx struct to correct values for vf mailbox
50079251f5eSSepherosa Ziehau  */
ixgbe_init_mbx_params_vf(struct ixgbe_hw * hw)50179251f5eSSepherosa Ziehau void ixgbe_init_mbx_params_vf(struct ixgbe_hw *hw)
50279251f5eSSepherosa Ziehau {
50379251f5eSSepherosa Ziehau 	struct ixgbe_mbx_info *mbx = &hw->mbx;
50479251f5eSSepherosa Ziehau 
50579251f5eSSepherosa Ziehau 	/* start mailbox as timed out and let the reset_hw call set the timeout
50679251f5eSSepherosa Ziehau 	 * value to begin communications */
50779251f5eSSepherosa Ziehau 	mbx->timeout = 0;
50879251f5eSSepherosa Ziehau 	mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;
50979251f5eSSepherosa Ziehau 
51079251f5eSSepherosa Ziehau 	mbx->size = IXGBE_VFMAILBOX_SIZE;
51179251f5eSSepherosa Ziehau 
51279251f5eSSepherosa Ziehau 	mbx->ops.read = ixgbe_read_mbx_vf;
51379251f5eSSepherosa Ziehau 	mbx->ops.write = ixgbe_write_mbx_vf;
51479251f5eSSepherosa Ziehau 	mbx->ops.read_posted = ixgbe_read_posted_mbx;
51579251f5eSSepherosa Ziehau 	mbx->ops.write_posted = ixgbe_write_posted_mbx;
51679251f5eSSepherosa Ziehau 	mbx->ops.check_for_msg = ixgbe_check_for_msg_vf;
51779251f5eSSepherosa Ziehau 	mbx->ops.check_for_ack = ixgbe_check_for_ack_vf;
51879251f5eSSepherosa Ziehau 	mbx->ops.check_for_rst = ixgbe_check_for_rst_vf;
51979251f5eSSepherosa Ziehau 
52079251f5eSSepherosa Ziehau 	mbx->stats.msgs_tx = 0;
52179251f5eSSepherosa Ziehau 	mbx->stats.msgs_rx = 0;
52279251f5eSSepherosa Ziehau 	mbx->stats.reqs = 0;
52379251f5eSSepherosa Ziehau 	mbx->stats.acks = 0;
52479251f5eSSepherosa Ziehau 	mbx->stats.rsts = 0;
52579251f5eSSepherosa Ziehau }
52679251f5eSSepherosa Ziehau 
ixgbe_check_for_bit_pf(struct ixgbe_hw * hw,u32 mask,s32 index)52779251f5eSSepherosa Ziehau static s32 ixgbe_check_for_bit_pf(struct ixgbe_hw *hw, u32 mask, s32 index)
52879251f5eSSepherosa Ziehau {
52979251f5eSSepherosa Ziehau 	u32 mbvficr = IXGBE_READ_REG(hw, IXGBE_MBVFICR(index));
53079251f5eSSepherosa Ziehau 	s32 ret_val = IXGBE_ERR_MBX;
53179251f5eSSepherosa Ziehau 
53279251f5eSSepherosa Ziehau 	if (mbvficr & mask) {
53379251f5eSSepherosa Ziehau 		ret_val = IXGBE_SUCCESS;
53479251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_MBVFICR(index), mask);
53579251f5eSSepherosa Ziehau 	}
53679251f5eSSepherosa Ziehau 
53779251f5eSSepherosa Ziehau 	return ret_val;
53879251f5eSSepherosa Ziehau }
53979251f5eSSepherosa Ziehau 
54079251f5eSSepherosa Ziehau /**
54179251f5eSSepherosa Ziehau  *  ixgbe_check_for_msg_pf - checks to see if the VF has sent mail
54279251f5eSSepherosa Ziehau  *  @hw: pointer to the HW structure
54379251f5eSSepherosa Ziehau  *  @vf_number: the VF index
54479251f5eSSepherosa Ziehau  *
54579251f5eSSepherosa Ziehau  *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
54679251f5eSSepherosa Ziehau  **/
ixgbe_check_for_msg_pf(struct ixgbe_hw * hw,u16 vf_number)54779251f5eSSepherosa Ziehau static s32 ixgbe_check_for_msg_pf(struct ixgbe_hw *hw, u16 vf_number)
54879251f5eSSepherosa Ziehau {
54979251f5eSSepherosa Ziehau 	s32 ret_val = IXGBE_ERR_MBX;
55079251f5eSSepherosa Ziehau 	s32 index = IXGBE_MBVFICR_INDEX(vf_number);
55179251f5eSSepherosa Ziehau 	u32 vf_bit = vf_number % 16;
55279251f5eSSepherosa Ziehau 
55379251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_check_for_msg_pf");
55479251f5eSSepherosa Ziehau 
55579251f5eSSepherosa Ziehau 	if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFREQ_VF1 << vf_bit,
55679251f5eSSepherosa Ziehau 				    index)) {
55779251f5eSSepherosa Ziehau 		ret_val = IXGBE_SUCCESS;
55879251f5eSSepherosa Ziehau 		hw->mbx.stats.reqs++;
55979251f5eSSepherosa Ziehau 	}
56079251f5eSSepherosa Ziehau 
56179251f5eSSepherosa Ziehau 	return ret_val;
56279251f5eSSepherosa Ziehau }
56379251f5eSSepherosa Ziehau 
56479251f5eSSepherosa Ziehau /**
56579251f5eSSepherosa Ziehau  *  ixgbe_check_for_ack_pf - checks to see if the VF has ACKed
56679251f5eSSepherosa Ziehau  *  @hw: pointer to the HW structure
56779251f5eSSepherosa Ziehau  *  @vf_number: the VF index
56879251f5eSSepherosa Ziehau  *
56979251f5eSSepherosa Ziehau  *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
57079251f5eSSepherosa Ziehau  **/
ixgbe_check_for_ack_pf(struct ixgbe_hw * hw,u16 vf_number)57179251f5eSSepherosa Ziehau static s32 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_number)
57279251f5eSSepherosa Ziehau {
57379251f5eSSepherosa Ziehau 	s32 ret_val = IXGBE_ERR_MBX;
57479251f5eSSepherosa Ziehau 	s32 index = IXGBE_MBVFICR_INDEX(vf_number);
57579251f5eSSepherosa Ziehau 	u32 vf_bit = vf_number % 16;
57679251f5eSSepherosa Ziehau 
57779251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_check_for_ack_pf");
57879251f5eSSepherosa Ziehau 
57979251f5eSSepherosa Ziehau 	if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFACK_VF1 << vf_bit,
58079251f5eSSepherosa Ziehau 				    index)) {
58179251f5eSSepherosa Ziehau 		ret_val = IXGBE_SUCCESS;
58279251f5eSSepherosa Ziehau 		hw->mbx.stats.acks++;
58379251f5eSSepherosa Ziehau 	}
58479251f5eSSepherosa Ziehau 
58579251f5eSSepherosa Ziehau 	return ret_val;
58679251f5eSSepherosa Ziehau }
58779251f5eSSepherosa Ziehau 
58879251f5eSSepherosa Ziehau /**
58979251f5eSSepherosa Ziehau  *  ixgbe_check_for_rst_pf - checks to see if the VF has reset
59079251f5eSSepherosa Ziehau  *  @hw: pointer to the HW structure
59179251f5eSSepherosa Ziehau  *  @vf_number: the VF index
59279251f5eSSepherosa Ziehau  *
59379251f5eSSepherosa Ziehau  *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
59479251f5eSSepherosa Ziehau  **/
ixgbe_check_for_rst_pf(struct ixgbe_hw * hw,u16 vf_number)59579251f5eSSepherosa Ziehau static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_number)
59679251f5eSSepherosa Ziehau {
59779251f5eSSepherosa Ziehau 	u32 reg_offset = (vf_number < 32) ? 0 : 1;
59879251f5eSSepherosa Ziehau 	u32 vf_shift = vf_number % 32;
59979251f5eSSepherosa Ziehau 	u32 vflre = 0;
60079251f5eSSepherosa Ziehau 	s32 ret_val = IXGBE_ERR_MBX;
60179251f5eSSepherosa Ziehau 
60279251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_check_for_rst_pf");
60379251f5eSSepherosa Ziehau 
60479251f5eSSepherosa Ziehau 	switch (hw->mac.type) {
60579251f5eSSepherosa Ziehau 	case ixgbe_mac_82599EB:
60679251f5eSSepherosa Ziehau 		vflre = IXGBE_READ_REG(hw, IXGBE_VFLRE(reg_offset));
60779251f5eSSepherosa Ziehau 		break;
60863d483cdSSepherosa Ziehau 	case ixgbe_mac_X550:
60963d483cdSSepherosa Ziehau 	case ixgbe_mac_X550EM_x:
61063d483cdSSepherosa Ziehau 	case ixgbe_mac_X550EM_a:
61179251f5eSSepherosa Ziehau 	case ixgbe_mac_X540:
61279251f5eSSepherosa Ziehau 		vflre = IXGBE_READ_REG(hw, IXGBE_VFLREC(reg_offset));
61379251f5eSSepherosa Ziehau 		break;
61479251f5eSSepherosa Ziehau 	default:
61579251f5eSSepherosa Ziehau 		break;
61679251f5eSSepherosa Ziehau 	}
61779251f5eSSepherosa Ziehau 
61879251f5eSSepherosa Ziehau 	if (vflre & (1 << vf_shift)) {
61979251f5eSSepherosa Ziehau 		ret_val = IXGBE_SUCCESS;
62079251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_VFLREC(reg_offset), (1 << vf_shift));
62179251f5eSSepherosa Ziehau 		hw->mbx.stats.rsts++;
62279251f5eSSepherosa Ziehau 	}
62379251f5eSSepherosa Ziehau 
62479251f5eSSepherosa Ziehau 	return ret_val;
62579251f5eSSepherosa Ziehau }
62679251f5eSSepherosa Ziehau 
62779251f5eSSepherosa Ziehau /**
62879251f5eSSepherosa Ziehau  *  ixgbe_obtain_mbx_lock_pf - obtain mailbox lock
62979251f5eSSepherosa Ziehau  *  @hw: pointer to the HW structure
63079251f5eSSepherosa Ziehau  *  @vf_number: the VF index
63179251f5eSSepherosa Ziehau  *
63279251f5eSSepherosa Ziehau  *  return SUCCESS if we obtained the mailbox lock
63379251f5eSSepherosa Ziehau  **/
ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw * hw,u16 vf_number)63479251f5eSSepherosa Ziehau static s32 ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_number)
63579251f5eSSepherosa Ziehau {
63679251f5eSSepherosa Ziehau 	s32 ret_val = IXGBE_ERR_MBX;
63779251f5eSSepherosa Ziehau 	u32 p2v_mailbox;
63879251f5eSSepherosa Ziehau 
63979251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_obtain_mbx_lock_pf");
64079251f5eSSepherosa Ziehau 
64179251f5eSSepherosa Ziehau 	/* Take ownership of the buffer */
64279251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_PFU);
64379251f5eSSepherosa Ziehau 
64479251f5eSSepherosa Ziehau 	/* reserve mailbox for vf use */
64579251f5eSSepherosa Ziehau 	p2v_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_number));
64679251f5eSSepherosa Ziehau 	if (p2v_mailbox & IXGBE_PFMAILBOX_PFU)
64779251f5eSSepherosa Ziehau 		ret_val = IXGBE_SUCCESS;
64879251f5eSSepherosa Ziehau 	else
64979251f5eSSepherosa Ziehau 		ERROR_REPORT2(IXGBE_ERROR_POLLING,
65079251f5eSSepherosa Ziehau 			   "Failed to obtain mailbox lock for VF%d", vf_number);
65179251f5eSSepherosa Ziehau 
65279251f5eSSepherosa Ziehau 
65379251f5eSSepherosa Ziehau 	return ret_val;
65479251f5eSSepherosa Ziehau }
65579251f5eSSepherosa Ziehau 
65679251f5eSSepherosa Ziehau /**
65779251f5eSSepherosa Ziehau  *  ixgbe_write_mbx_pf - Places a message in the mailbox
65879251f5eSSepherosa Ziehau  *  @hw: pointer to the HW structure
65979251f5eSSepherosa Ziehau  *  @msg: The message buffer
66079251f5eSSepherosa Ziehau  *  @size: Length of buffer
66179251f5eSSepherosa Ziehau  *  @vf_number: the VF index
66279251f5eSSepherosa Ziehau  *
66379251f5eSSepherosa Ziehau  *  returns SUCCESS if it successfully copied message into the buffer
66479251f5eSSepherosa Ziehau  **/
ixgbe_write_mbx_pf(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 vf_number)66579251f5eSSepherosa Ziehau static s32 ixgbe_write_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
66679251f5eSSepherosa Ziehau 			      u16 vf_number)
66779251f5eSSepherosa Ziehau {
66879251f5eSSepherosa Ziehau 	s32 ret_val;
66979251f5eSSepherosa Ziehau 	u16 i;
67079251f5eSSepherosa Ziehau 
67179251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_write_mbx_pf");
67279251f5eSSepherosa Ziehau 
67379251f5eSSepherosa Ziehau 	/* lock the mailbox to prevent pf/vf race condition */
67479251f5eSSepherosa Ziehau 	ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number);
67579251f5eSSepherosa Ziehau 	if (ret_val)
67679251f5eSSepherosa Ziehau 		goto out_no_write;
67779251f5eSSepherosa Ziehau 
67879251f5eSSepherosa Ziehau 	/* flush msg and acks as we are overwriting the message buffer */
67979251f5eSSepherosa Ziehau 	ixgbe_check_for_msg_pf(hw, vf_number);
68079251f5eSSepherosa Ziehau 	ixgbe_check_for_ack_pf(hw, vf_number);
68179251f5eSSepherosa Ziehau 
68279251f5eSSepherosa Ziehau 	/* copy the caller specified message to the mailbox memory buffer */
68379251f5eSSepherosa Ziehau 	for (i = 0; i < size; i++)
68479251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i, msg[i]);
68579251f5eSSepherosa Ziehau 
68679251f5eSSepherosa Ziehau 	/* Interrupt VF to tell it a message has been sent and release buffer*/
68779251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_STS);
68879251f5eSSepherosa Ziehau 
68979251f5eSSepherosa Ziehau 	/* update stats */
69079251f5eSSepherosa Ziehau 	hw->mbx.stats.msgs_tx++;
69179251f5eSSepherosa Ziehau 
69279251f5eSSepherosa Ziehau out_no_write:
69379251f5eSSepherosa Ziehau 	return ret_val;
69479251f5eSSepherosa Ziehau 
69579251f5eSSepherosa Ziehau }
69679251f5eSSepherosa Ziehau 
69779251f5eSSepherosa Ziehau /**
69879251f5eSSepherosa Ziehau  *  ixgbe_read_mbx_pf - Read a message from the mailbox
69979251f5eSSepherosa Ziehau  *  @hw: pointer to the HW structure
70079251f5eSSepherosa Ziehau  *  @msg: The message buffer
70179251f5eSSepherosa Ziehau  *  @size: Length of buffer
70279251f5eSSepherosa Ziehau  *  @vf_number: the VF index
70379251f5eSSepherosa Ziehau  *
70479251f5eSSepherosa Ziehau  *  This function copies a message from the mailbox buffer to the caller's
70579251f5eSSepherosa Ziehau  *  memory buffer.  The presumption is that the caller knows that there was
70679251f5eSSepherosa Ziehau  *  a message due to a VF request so no polling for message is needed.
70779251f5eSSepherosa Ziehau  **/
ixgbe_read_mbx_pf(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 vf_number)70879251f5eSSepherosa Ziehau static s32 ixgbe_read_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
70979251f5eSSepherosa Ziehau 			     u16 vf_number)
71079251f5eSSepherosa Ziehau {
71179251f5eSSepherosa Ziehau 	s32 ret_val;
71279251f5eSSepherosa Ziehau 	u16 i;
71379251f5eSSepherosa Ziehau 
71479251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_read_mbx_pf");
71579251f5eSSepherosa Ziehau 
71679251f5eSSepherosa Ziehau 	/* lock the mailbox to prevent pf/vf race condition */
71779251f5eSSepherosa Ziehau 	ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number);
71879251f5eSSepherosa Ziehau 	if (ret_val)
71979251f5eSSepherosa Ziehau 		goto out_no_read;
72079251f5eSSepherosa Ziehau 
72179251f5eSSepherosa Ziehau 	/* copy the message to the mailbox memory buffer */
72279251f5eSSepherosa Ziehau 	for (i = 0; i < size; i++)
72379251f5eSSepherosa Ziehau 		msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i);
72479251f5eSSepherosa Ziehau 
72579251f5eSSepherosa Ziehau 	/* Acknowledge the message and release buffer */
72679251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_ACK);
72779251f5eSSepherosa Ziehau 
72879251f5eSSepherosa Ziehau 	/* update stats */
72979251f5eSSepherosa Ziehau 	hw->mbx.stats.msgs_rx++;
73079251f5eSSepherosa Ziehau 
73179251f5eSSepherosa Ziehau out_no_read:
73279251f5eSSepherosa Ziehau 	return ret_val;
73379251f5eSSepherosa Ziehau }
73479251f5eSSepherosa Ziehau 
73579251f5eSSepherosa Ziehau /**
73679251f5eSSepherosa Ziehau  *  ixgbe_init_mbx_params_pf - set initial values for pf mailbox
73779251f5eSSepherosa Ziehau  *  @hw: pointer to the HW structure
73879251f5eSSepherosa Ziehau  *
73979251f5eSSepherosa Ziehau  *  Initializes the hw->mbx struct to correct values for pf mailbox
74079251f5eSSepherosa Ziehau  */
ixgbe_init_mbx_params_pf(struct ixgbe_hw * hw)74179251f5eSSepherosa Ziehau void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw)
74279251f5eSSepherosa Ziehau {
74379251f5eSSepherosa Ziehau 	struct ixgbe_mbx_info *mbx = &hw->mbx;
74479251f5eSSepherosa Ziehau 
74579251f5eSSepherosa Ziehau 	if (hw->mac.type != ixgbe_mac_82599EB &&
74663d483cdSSepherosa Ziehau 	    hw->mac.type != ixgbe_mac_X550 &&
74763d483cdSSepherosa Ziehau 	    hw->mac.type != ixgbe_mac_X550EM_x &&
74863d483cdSSepherosa Ziehau 	    hw->mac.type != ixgbe_mac_X550EM_a &&
74979251f5eSSepherosa Ziehau 	    hw->mac.type != ixgbe_mac_X540)
75079251f5eSSepherosa Ziehau 		return;
75179251f5eSSepherosa Ziehau 
75279251f5eSSepherosa Ziehau 	mbx->timeout = 0;
75379251f5eSSepherosa Ziehau 	mbx->usec_delay = 0;
75479251f5eSSepherosa Ziehau 
75579251f5eSSepherosa Ziehau 	mbx->size = IXGBE_VFMAILBOX_SIZE;
75679251f5eSSepherosa Ziehau 
75779251f5eSSepherosa Ziehau 	mbx->ops.read = ixgbe_read_mbx_pf;
75879251f5eSSepherosa Ziehau 	mbx->ops.write = ixgbe_write_mbx_pf;
75979251f5eSSepherosa Ziehau 	mbx->ops.read_posted = ixgbe_read_posted_mbx;
76079251f5eSSepherosa Ziehau 	mbx->ops.write_posted = ixgbe_write_posted_mbx;
76179251f5eSSepherosa Ziehau 	mbx->ops.check_for_msg = ixgbe_check_for_msg_pf;
76279251f5eSSepherosa Ziehau 	mbx->ops.check_for_ack = ixgbe_check_for_ack_pf;
76379251f5eSSepherosa Ziehau 	mbx->ops.check_for_rst = ixgbe_check_for_rst_pf;
76479251f5eSSepherosa Ziehau 
76579251f5eSSepherosa Ziehau 	mbx->stats.msgs_tx = 0;
76679251f5eSSepherosa Ziehau 	mbx->stats.msgs_rx = 0;
76779251f5eSSepherosa Ziehau 	mbx->stats.reqs = 0;
76879251f5eSSepherosa Ziehau 	mbx->stats.acks = 0;
76979251f5eSSepherosa Ziehau 	mbx->stats.rsts = 0;
77079251f5eSSepherosa Ziehau }
771