xref: /dflybsd-src/sys/dev/netif/ig_hal/e1000_mbx.c (revision 65aebe9f9faf98a2c7eaca700e786d06c34a9929)
162583d18SSepherosa Ziehau /******************************************************************************
262583d18SSepherosa Ziehau 
3*65aebe9fSSepherosa Ziehau   Copyright (c) 2001-2016, Intel Corporation
462583d18SSepherosa Ziehau   All rights reserved.
562583d18SSepherosa Ziehau 
662583d18SSepherosa Ziehau   Redistribution and use in source and binary forms, with or without
762583d18SSepherosa Ziehau   modification, are permitted provided that the following conditions are met:
862583d18SSepherosa Ziehau 
962583d18SSepherosa Ziehau    1. Redistributions of source code must retain the above copyright notice,
1062583d18SSepherosa Ziehau       this list of conditions and the following disclaimer.
1162583d18SSepherosa Ziehau 
1262583d18SSepherosa Ziehau    2. Redistributions in binary form must reproduce the above copyright
1362583d18SSepherosa Ziehau       notice, this list of conditions and the following disclaimer in the
1462583d18SSepherosa Ziehau       documentation and/or other materials provided with the distribution.
1562583d18SSepherosa Ziehau 
1662583d18SSepherosa Ziehau    3. Neither the name of the Intel Corporation nor the names of its
1762583d18SSepherosa Ziehau       contributors may be used to endorse or promote products derived from
1862583d18SSepherosa Ziehau       this software without specific prior written permission.
1962583d18SSepherosa Ziehau 
2062583d18SSepherosa Ziehau   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2162583d18SSepherosa Ziehau   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2262583d18SSepherosa Ziehau   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2362583d18SSepherosa Ziehau   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
2462583d18SSepherosa Ziehau   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2562583d18SSepherosa Ziehau   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2662583d18SSepherosa Ziehau   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2762583d18SSepherosa Ziehau   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2862583d18SSepherosa Ziehau   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2962583d18SSepherosa Ziehau   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3062583d18SSepherosa Ziehau   POSSIBILITY OF SUCH DAMAGE.
3162583d18SSepherosa Ziehau 
3262583d18SSepherosa Ziehau ******************************************************************************/
3362583d18SSepherosa Ziehau /*$FreeBSD$*/
3462583d18SSepherosa Ziehau 
3562583d18SSepherosa Ziehau #include "e1000_mbx.h"
3662583d18SSepherosa Ziehau 
3762583d18SSepherosa Ziehau /**
3862583d18SSepherosa Ziehau  *  e1000_null_mbx_check_for_flag - No-op function, return 0
3962583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
4062583d18SSepherosa Ziehau  **/
e1000_null_mbx_check_for_flag(struct e1000_hw E1000_UNUSEDARG * hw,u16 E1000_UNUSEDARG mbx_id)41379ebbe7SSepherosa Ziehau static s32 e1000_null_mbx_check_for_flag(struct e1000_hw E1000_UNUSEDARG *hw,
42379ebbe7SSepherosa Ziehau 					 u16 E1000_UNUSEDARG mbx_id)
4362583d18SSepherosa Ziehau {
4462583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_null_mbx_check_flag");
4562583d18SSepherosa Ziehau 
4662583d18SSepherosa Ziehau 	return E1000_SUCCESS;
4762583d18SSepherosa Ziehau }
4862583d18SSepherosa Ziehau 
4962583d18SSepherosa Ziehau /**
5062583d18SSepherosa Ziehau  *  e1000_null_mbx_transact - No-op function, return 0
5162583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
5262583d18SSepherosa Ziehau  **/
e1000_null_mbx_transact(struct e1000_hw E1000_UNUSEDARG * hw,u32 E1000_UNUSEDARG * msg,u16 E1000_UNUSEDARG size,u16 E1000_UNUSEDARG mbx_id)53379ebbe7SSepherosa Ziehau static s32 e1000_null_mbx_transact(struct e1000_hw E1000_UNUSEDARG *hw,
54379ebbe7SSepherosa Ziehau 				   u32 E1000_UNUSEDARG *msg,
55379ebbe7SSepherosa Ziehau 				   u16 E1000_UNUSEDARG size,
56379ebbe7SSepherosa Ziehau 				   u16 E1000_UNUSEDARG mbx_id)
5762583d18SSepherosa Ziehau {
5862583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_null_mbx_rw_msg");
5962583d18SSepherosa Ziehau 
6062583d18SSepherosa Ziehau 	return E1000_SUCCESS;
6162583d18SSepherosa Ziehau }
6262583d18SSepherosa Ziehau 
6362583d18SSepherosa Ziehau /**
6462583d18SSepherosa Ziehau  *  e1000_read_mbx - Reads a message from the mailbox
6562583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
6662583d18SSepherosa Ziehau  *  @msg: The message buffer
6762583d18SSepherosa Ziehau  *  @size: Length of buffer
6862583d18SSepherosa Ziehau  *  @mbx_id: id of mailbox to read
6962583d18SSepherosa Ziehau  *
7062583d18SSepherosa Ziehau  *  returns SUCCESS if it successfuly read message from buffer
7162583d18SSepherosa Ziehau  **/
e1000_read_mbx(struct e1000_hw * hw,u32 * msg,u16 size,u16 mbx_id)7262583d18SSepherosa Ziehau s32 e1000_read_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
7362583d18SSepherosa Ziehau {
7462583d18SSepherosa Ziehau 	struct e1000_mbx_info *mbx = &hw->mbx;
7562583d18SSepherosa Ziehau 	s32 ret_val = -E1000_ERR_MBX;
7662583d18SSepherosa Ziehau 
7762583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_read_mbx");
7862583d18SSepherosa Ziehau 
7962583d18SSepherosa Ziehau 	/* limit read to size of mailbox */
8062583d18SSepherosa Ziehau 	if (size > mbx->size)
8162583d18SSepherosa Ziehau 		size = mbx->size;
8262583d18SSepherosa Ziehau 
8362583d18SSepherosa Ziehau 	if (mbx->ops.read)
8462583d18SSepherosa Ziehau 		ret_val = mbx->ops.read(hw, msg, size, mbx_id);
8562583d18SSepherosa Ziehau 
8662583d18SSepherosa Ziehau 	return ret_val;
8762583d18SSepherosa Ziehau }
8862583d18SSepherosa Ziehau 
8962583d18SSepherosa Ziehau /**
9062583d18SSepherosa Ziehau  *  e1000_write_mbx - Write a message to the mailbox
9162583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
9262583d18SSepherosa Ziehau  *  @msg: The message buffer
9362583d18SSepherosa Ziehau  *  @size: Length of buffer
9462583d18SSepherosa Ziehau  *  @mbx_id: id of mailbox to write
9562583d18SSepherosa Ziehau  *
9662583d18SSepherosa Ziehau  *  returns SUCCESS if it successfully copied message into the buffer
9762583d18SSepherosa Ziehau  **/
e1000_write_mbx(struct e1000_hw * hw,u32 * msg,u16 size,u16 mbx_id)9862583d18SSepherosa Ziehau s32 e1000_write_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
9962583d18SSepherosa Ziehau {
10062583d18SSepherosa Ziehau 	struct e1000_mbx_info *mbx = &hw->mbx;
10162583d18SSepherosa Ziehau 	s32 ret_val = E1000_SUCCESS;
10262583d18SSepherosa Ziehau 
10362583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_write_mbx");
10462583d18SSepherosa Ziehau 
10562583d18SSepherosa Ziehau 	if (size > mbx->size)
10662583d18SSepherosa Ziehau 		ret_val = -E1000_ERR_MBX;
10762583d18SSepherosa Ziehau 
10862583d18SSepherosa Ziehau 	else if (mbx->ops.write)
10962583d18SSepherosa Ziehau 		ret_val = mbx->ops.write(hw, msg, size, mbx_id);
11062583d18SSepherosa Ziehau 
11162583d18SSepherosa Ziehau 	return ret_val;
11262583d18SSepherosa Ziehau }
11362583d18SSepherosa Ziehau 
11462583d18SSepherosa Ziehau /**
11562583d18SSepherosa Ziehau  *  e1000_check_for_msg - checks to see if someone sent us mail
11662583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
11762583d18SSepherosa Ziehau  *  @mbx_id: id of mailbox to check
11862583d18SSepherosa Ziehau  *
11962583d18SSepherosa Ziehau  *  returns SUCCESS if the Status bit was found or else ERR_MBX
12062583d18SSepherosa Ziehau  **/
e1000_check_for_msg(struct e1000_hw * hw,u16 mbx_id)12162583d18SSepherosa Ziehau s32 e1000_check_for_msg(struct e1000_hw *hw, u16 mbx_id)
12262583d18SSepherosa Ziehau {
12362583d18SSepherosa Ziehau 	struct e1000_mbx_info *mbx = &hw->mbx;
12462583d18SSepherosa Ziehau 	s32 ret_val = -E1000_ERR_MBX;
12562583d18SSepherosa Ziehau 
12662583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_check_for_msg");
12762583d18SSepherosa Ziehau 
12862583d18SSepherosa Ziehau 	if (mbx->ops.check_for_msg)
12962583d18SSepherosa Ziehau 		ret_val = mbx->ops.check_for_msg(hw, mbx_id);
13062583d18SSepherosa Ziehau 
13162583d18SSepherosa Ziehau 	return ret_val;
13262583d18SSepherosa Ziehau }
13362583d18SSepherosa Ziehau 
13462583d18SSepherosa Ziehau /**
13562583d18SSepherosa Ziehau  *  e1000_check_for_ack - checks to see if someone sent us ACK
13662583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
13762583d18SSepherosa Ziehau  *  @mbx_id: id of mailbox to check
13862583d18SSepherosa Ziehau  *
13962583d18SSepherosa Ziehau  *  returns SUCCESS if the Status bit was found or else ERR_MBX
14062583d18SSepherosa Ziehau  **/
e1000_check_for_ack(struct e1000_hw * hw,u16 mbx_id)14162583d18SSepherosa Ziehau s32 e1000_check_for_ack(struct e1000_hw *hw, u16 mbx_id)
14262583d18SSepherosa Ziehau {
14362583d18SSepherosa Ziehau 	struct e1000_mbx_info *mbx = &hw->mbx;
14462583d18SSepherosa Ziehau 	s32 ret_val = -E1000_ERR_MBX;
14562583d18SSepherosa Ziehau 
14662583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_check_for_ack");
14762583d18SSepherosa Ziehau 
14862583d18SSepherosa Ziehau 	if (mbx->ops.check_for_ack)
14962583d18SSepherosa Ziehau 		ret_val = mbx->ops.check_for_ack(hw, mbx_id);
15062583d18SSepherosa Ziehau 
15162583d18SSepherosa Ziehau 	return ret_val;
15262583d18SSepherosa Ziehau }
15362583d18SSepherosa Ziehau 
15462583d18SSepherosa Ziehau /**
15562583d18SSepherosa Ziehau  *  e1000_check_for_rst - checks to see if other side has reset
15662583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
15762583d18SSepherosa Ziehau  *  @mbx_id: id of mailbox to check
15862583d18SSepherosa Ziehau  *
15962583d18SSepherosa Ziehau  *  returns SUCCESS if the Status bit was found or else ERR_MBX
16062583d18SSepherosa Ziehau  **/
e1000_check_for_rst(struct e1000_hw * hw,u16 mbx_id)16162583d18SSepherosa Ziehau s32 e1000_check_for_rst(struct e1000_hw *hw, u16 mbx_id)
16262583d18SSepherosa Ziehau {
16362583d18SSepherosa Ziehau 	struct e1000_mbx_info *mbx = &hw->mbx;
16462583d18SSepherosa Ziehau 	s32 ret_val = -E1000_ERR_MBX;
16562583d18SSepherosa Ziehau 
16662583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_check_for_rst");
16762583d18SSepherosa Ziehau 
16862583d18SSepherosa Ziehau 	if (mbx->ops.check_for_rst)
16962583d18SSepherosa Ziehau 		ret_val = mbx->ops.check_for_rst(hw, mbx_id);
17062583d18SSepherosa Ziehau 
17162583d18SSepherosa Ziehau 	return ret_val;
17262583d18SSepherosa Ziehau }
17362583d18SSepherosa Ziehau 
17462583d18SSepherosa Ziehau /**
17562583d18SSepherosa Ziehau  *  e1000_poll_for_msg - Wait for message notification
17662583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
17762583d18SSepherosa Ziehau  *  @mbx_id: id of mailbox to write
17862583d18SSepherosa Ziehau  *
17962583d18SSepherosa Ziehau  *  returns SUCCESS if it successfully received a message notification
18062583d18SSepherosa Ziehau  **/
e1000_poll_for_msg(struct e1000_hw * hw,u16 mbx_id)18162583d18SSepherosa Ziehau static s32 e1000_poll_for_msg(struct e1000_hw *hw, u16 mbx_id)
18262583d18SSepherosa Ziehau {
18362583d18SSepherosa Ziehau 	struct e1000_mbx_info *mbx = &hw->mbx;
18462583d18SSepherosa Ziehau 	int countdown = mbx->timeout;
18562583d18SSepherosa Ziehau 
18662583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_poll_for_msg");
18762583d18SSepherosa Ziehau 
18862583d18SSepherosa Ziehau 	if (!countdown || !mbx->ops.check_for_msg)
18962583d18SSepherosa Ziehau 		goto out;
19062583d18SSepherosa Ziehau 
19162583d18SSepherosa Ziehau 	while (countdown && mbx->ops.check_for_msg(hw, mbx_id)) {
19262583d18SSepherosa Ziehau 		countdown--;
19362583d18SSepherosa Ziehau 		if (!countdown)
19462583d18SSepherosa Ziehau 			break;
19562583d18SSepherosa Ziehau 		usec_delay(mbx->usec_delay);
19662583d18SSepherosa Ziehau 	}
19762583d18SSepherosa Ziehau 
19862583d18SSepherosa Ziehau 	/* if we failed, all future posted messages fail until reset */
19962583d18SSepherosa Ziehau 	if (!countdown)
20062583d18SSepherosa Ziehau 		mbx->timeout = 0;
20162583d18SSepherosa Ziehau out:
20262583d18SSepherosa Ziehau 	return countdown ? E1000_SUCCESS : -E1000_ERR_MBX;
20362583d18SSepherosa Ziehau }
20462583d18SSepherosa Ziehau 
20562583d18SSepherosa Ziehau /**
20662583d18SSepherosa Ziehau  *  e1000_poll_for_ack - Wait for message acknowledgement
20762583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
20862583d18SSepherosa Ziehau  *  @mbx_id: id of mailbox to write
20962583d18SSepherosa Ziehau  *
21062583d18SSepherosa Ziehau  *  returns SUCCESS if it successfully received a message acknowledgement
21162583d18SSepherosa Ziehau  **/
e1000_poll_for_ack(struct e1000_hw * hw,u16 mbx_id)21262583d18SSepherosa Ziehau static s32 e1000_poll_for_ack(struct e1000_hw *hw, u16 mbx_id)
21362583d18SSepherosa Ziehau {
21462583d18SSepherosa Ziehau 	struct e1000_mbx_info *mbx = &hw->mbx;
21562583d18SSepherosa Ziehau 	int countdown = mbx->timeout;
21662583d18SSepherosa Ziehau 
21762583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_poll_for_ack");
21862583d18SSepherosa Ziehau 
21962583d18SSepherosa Ziehau 	if (!countdown || !mbx->ops.check_for_ack)
22062583d18SSepherosa Ziehau 		goto out;
22162583d18SSepherosa Ziehau 
22262583d18SSepherosa Ziehau 	while (countdown && mbx->ops.check_for_ack(hw, mbx_id)) {
22362583d18SSepherosa Ziehau 		countdown--;
22462583d18SSepherosa Ziehau 		if (!countdown)
22562583d18SSepherosa Ziehau 			break;
22662583d18SSepherosa Ziehau 		usec_delay(mbx->usec_delay);
22762583d18SSepherosa Ziehau 	}
22862583d18SSepherosa Ziehau 
22962583d18SSepherosa Ziehau 	/* if we failed, all future posted messages fail until reset */
23062583d18SSepherosa Ziehau 	if (!countdown)
23162583d18SSepherosa Ziehau 		mbx->timeout = 0;
23262583d18SSepherosa Ziehau out:
23362583d18SSepherosa Ziehau 	return countdown ? E1000_SUCCESS : -E1000_ERR_MBX;
23462583d18SSepherosa Ziehau }
23562583d18SSepherosa Ziehau 
23662583d18SSepherosa Ziehau /**
23762583d18SSepherosa Ziehau  *  e1000_read_posted_mbx - Wait for message notification and receive message
23862583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
23962583d18SSepherosa Ziehau  *  @msg: The message buffer
24062583d18SSepherosa Ziehau  *  @size: Length of buffer
24162583d18SSepherosa Ziehau  *  @mbx_id: id of mailbox to write
24262583d18SSepherosa Ziehau  *
24362583d18SSepherosa Ziehau  *  returns SUCCESS if it successfully received a message notification and
24462583d18SSepherosa Ziehau  *  copied it into the receive buffer.
24562583d18SSepherosa Ziehau  **/
e1000_read_posted_mbx(struct e1000_hw * hw,u32 * msg,u16 size,u16 mbx_id)24662583d18SSepherosa Ziehau s32 e1000_read_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
24762583d18SSepherosa Ziehau {
24862583d18SSepherosa Ziehau 	struct e1000_mbx_info *mbx = &hw->mbx;
24962583d18SSepherosa Ziehau 	s32 ret_val = -E1000_ERR_MBX;
25062583d18SSepherosa Ziehau 
25162583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_read_posted_mbx");
25262583d18SSepherosa Ziehau 
25362583d18SSepherosa Ziehau 	if (!mbx->ops.read)
25462583d18SSepherosa Ziehau 		goto out;
25562583d18SSepherosa Ziehau 
25662583d18SSepherosa Ziehau 	ret_val = e1000_poll_for_msg(hw, mbx_id);
25762583d18SSepherosa Ziehau 
25862583d18SSepherosa Ziehau 	/* if ack received read message, otherwise we timed out */
25962583d18SSepherosa Ziehau 	if (!ret_val)
26062583d18SSepherosa Ziehau 		ret_val = mbx->ops.read(hw, msg, size, mbx_id);
26162583d18SSepherosa Ziehau out:
26262583d18SSepherosa Ziehau 	return ret_val;
26362583d18SSepherosa Ziehau }
26462583d18SSepherosa Ziehau 
26562583d18SSepherosa Ziehau /**
26662583d18SSepherosa Ziehau  *  e1000_write_posted_mbx - Write a message to the mailbox, wait for ack
26762583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
26862583d18SSepherosa Ziehau  *  @msg: The message buffer
26962583d18SSepherosa Ziehau  *  @size: Length of buffer
27062583d18SSepherosa Ziehau  *  @mbx_id: id of mailbox to write
27162583d18SSepherosa Ziehau  *
27262583d18SSepherosa Ziehau  *  returns SUCCESS if it successfully copied message into the buffer and
27362583d18SSepherosa Ziehau  *  received an ack to that message within delay * timeout period
27462583d18SSepherosa Ziehau  **/
e1000_write_posted_mbx(struct e1000_hw * hw,u32 * msg,u16 size,u16 mbx_id)27562583d18SSepherosa Ziehau s32 e1000_write_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
27662583d18SSepherosa Ziehau {
27762583d18SSepherosa Ziehau 	struct e1000_mbx_info *mbx = &hw->mbx;
27862583d18SSepherosa Ziehau 	s32 ret_val = -E1000_ERR_MBX;
27962583d18SSepherosa Ziehau 
28062583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_write_posted_mbx");
28162583d18SSepherosa Ziehau 
28262583d18SSepherosa Ziehau 	/* exit if either we can't write or there isn't a defined timeout */
28362583d18SSepherosa Ziehau 	if (!mbx->ops.write || !mbx->timeout)
28462583d18SSepherosa Ziehau 		goto out;
28562583d18SSepherosa Ziehau 
28662583d18SSepherosa Ziehau 	/* send msg */
28762583d18SSepherosa Ziehau 	ret_val = mbx->ops.write(hw, msg, size, mbx_id);
28862583d18SSepherosa Ziehau 
28962583d18SSepherosa Ziehau 	/* if msg sent wait until we receive an ack */
29062583d18SSepherosa Ziehau 	if (!ret_val)
29162583d18SSepherosa Ziehau 		ret_val = e1000_poll_for_ack(hw, mbx_id);
29262583d18SSepherosa Ziehau out:
29362583d18SSepherosa Ziehau 	return ret_val;
29462583d18SSepherosa Ziehau }
29562583d18SSepherosa Ziehau 
29662583d18SSepherosa Ziehau /**
29762583d18SSepherosa Ziehau  *  e1000_init_mbx_ops_generic - Initialize mbx function pointers
29862583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
29962583d18SSepherosa Ziehau  *
30062583d18SSepherosa Ziehau  *  Sets the function pointers to no-op functions
30162583d18SSepherosa Ziehau  **/
e1000_init_mbx_ops_generic(struct e1000_hw * hw)30262583d18SSepherosa Ziehau void e1000_init_mbx_ops_generic(struct e1000_hw *hw)
30362583d18SSepherosa Ziehau {
30462583d18SSepherosa Ziehau 	struct e1000_mbx_info *mbx = &hw->mbx;
30562583d18SSepherosa Ziehau 	mbx->ops.init_params = e1000_null_ops_generic;
30662583d18SSepherosa Ziehau 	mbx->ops.read = e1000_null_mbx_transact;
30762583d18SSepherosa Ziehau 	mbx->ops.write = e1000_null_mbx_transact;
30862583d18SSepherosa Ziehau 	mbx->ops.check_for_msg = e1000_null_mbx_check_for_flag;
30962583d18SSepherosa Ziehau 	mbx->ops.check_for_ack = e1000_null_mbx_check_for_flag;
31062583d18SSepherosa Ziehau 	mbx->ops.check_for_rst = e1000_null_mbx_check_for_flag;
31162583d18SSepherosa Ziehau 	mbx->ops.read_posted = e1000_read_posted_mbx;
31262583d18SSepherosa Ziehau 	mbx->ops.write_posted = e1000_write_posted_mbx;
31362583d18SSepherosa Ziehau }
31462583d18SSepherosa Ziehau 
31562583d18SSepherosa Ziehau /**
31662583d18SSepherosa Ziehau  *  e1000_read_v2p_mailbox - read v2p mailbox
31762583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
31862583d18SSepherosa Ziehau  *
31962583d18SSepherosa Ziehau  *  This function is used to read the v2p mailbox without losing the read to
32062583d18SSepherosa Ziehau  *  clear status bits.
32162583d18SSepherosa Ziehau  **/
e1000_read_v2p_mailbox(struct e1000_hw * hw)32262583d18SSepherosa Ziehau static u32 e1000_read_v2p_mailbox(struct e1000_hw *hw)
32362583d18SSepherosa Ziehau {
32462583d18SSepherosa Ziehau 	u32 v2p_mailbox = E1000_READ_REG(hw, E1000_V2PMAILBOX(0));
32562583d18SSepherosa Ziehau 
32662583d18SSepherosa Ziehau 	v2p_mailbox |= hw->dev_spec.vf.v2p_mailbox;
32762583d18SSepherosa Ziehau 	hw->dev_spec.vf.v2p_mailbox |= v2p_mailbox & E1000_V2PMAILBOX_R2C_BITS;
32862583d18SSepherosa Ziehau 
32962583d18SSepherosa Ziehau 	return v2p_mailbox;
33062583d18SSepherosa Ziehau }
33162583d18SSepherosa Ziehau 
33262583d18SSepherosa Ziehau /**
33362583d18SSepherosa Ziehau  *  e1000_check_for_bit_vf - Determine if a status bit was set
33462583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
33562583d18SSepherosa Ziehau  *  @mask: bitmask for bits to be tested and cleared
33662583d18SSepherosa Ziehau  *
33762583d18SSepherosa Ziehau  *  This function is used to check for the read to clear bits within
33862583d18SSepherosa Ziehau  *  the V2P mailbox.
33962583d18SSepherosa Ziehau  **/
e1000_check_for_bit_vf(struct e1000_hw * hw,u32 mask)34062583d18SSepherosa Ziehau static s32 e1000_check_for_bit_vf(struct e1000_hw *hw, u32 mask)
34162583d18SSepherosa Ziehau {
34262583d18SSepherosa Ziehau 	u32 v2p_mailbox = e1000_read_v2p_mailbox(hw);
34362583d18SSepherosa Ziehau 	s32 ret_val = -E1000_ERR_MBX;
34462583d18SSepherosa Ziehau 
34562583d18SSepherosa Ziehau 	if (v2p_mailbox & mask)
34662583d18SSepherosa Ziehau 		ret_val = E1000_SUCCESS;
34762583d18SSepherosa Ziehau 
34862583d18SSepherosa Ziehau 	hw->dev_spec.vf.v2p_mailbox &= ~mask;
34962583d18SSepherosa Ziehau 
35062583d18SSepherosa Ziehau 	return ret_val;
35162583d18SSepherosa Ziehau }
35262583d18SSepherosa Ziehau 
35362583d18SSepherosa Ziehau /**
35462583d18SSepherosa Ziehau  *  e1000_check_for_msg_vf - checks to see if the PF has sent mail
35562583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
35662583d18SSepherosa Ziehau  *  @mbx_id: id of mailbox to check
35762583d18SSepherosa Ziehau  *
35862583d18SSepherosa Ziehau  *  returns SUCCESS if the PF has set the Status bit or else ERR_MBX
35962583d18SSepherosa Ziehau  **/
e1000_check_for_msg_vf(struct e1000_hw * hw,u16 E1000_UNUSEDARG mbx_id)360379ebbe7SSepherosa Ziehau static s32 e1000_check_for_msg_vf(struct e1000_hw *hw,
361379ebbe7SSepherosa Ziehau 				  u16 E1000_UNUSEDARG mbx_id)
36262583d18SSepherosa Ziehau {
36362583d18SSepherosa Ziehau 	s32 ret_val = -E1000_ERR_MBX;
36462583d18SSepherosa Ziehau 
36562583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_check_for_msg_vf");
36662583d18SSepherosa Ziehau 
36762583d18SSepherosa Ziehau 	if (!e1000_check_for_bit_vf(hw, E1000_V2PMAILBOX_PFSTS)) {
36862583d18SSepherosa Ziehau 		ret_val = E1000_SUCCESS;
36962583d18SSepherosa Ziehau 		hw->mbx.stats.reqs++;
37062583d18SSepherosa Ziehau 	}
37162583d18SSepherosa Ziehau 
37262583d18SSepherosa Ziehau 	return ret_val;
37362583d18SSepherosa Ziehau }
37462583d18SSepherosa Ziehau 
37562583d18SSepherosa Ziehau /**
37662583d18SSepherosa Ziehau  *  e1000_check_for_ack_vf - checks to see if the PF has ACK'd
37762583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
37862583d18SSepherosa Ziehau  *  @mbx_id: id of mailbox to check
37962583d18SSepherosa Ziehau  *
38062583d18SSepherosa Ziehau  *  returns SUCCESS if the PF has set the ACK bit or else ERR_MBX
38162583d18SSepherosa Ziehau  **/
e1000_check_for_ack_vf(struct e1000_hw * hw,u16 E1000_UNUSEDARG mbx_id)382379ebbe7SSepherosa Ziehau static s32 e1000_check_for_ack_vf(struct e1000_hw *hw,
383379ebbe7SSepherosa Ziehau 				  u16 E1000_UNUSEDARG mbx_id)
38462583d18SSepherosa Ziehau {
38562583d18SSepherosa Ziehau 	s32 ret_val = -E1000_ERR_MBX;
38662583d18SSepherosa Ziehau 
38762583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_check_for_ack_vf");
38862583d18SSepherosa Ziehau 
38962583d18SSepherosa Ziehau 	if (!e1000_check_for_bit_vf(hw, E1000_V2PMAILBOX_PFACK)) {
39062583d18SSepherosa Ziehau 		ret_val = E1000_SUCCESS;
39162583d18SSepherosa Ziehau 		hw->mbx.stats.acks++;
39262583d18SSepherosa Ziehau 	}
39362583d18SSepherosa Ziehau 
39462583d18SSepherosa Ziehau 	return ret_val;
39562583d18SSepherosa Ziehau }
39662583d18SSepherosa Ziehau 
39762583d18SSepherosa Ziehau /**
39862583d18SSepherosa Ziehau  *  e1000_check_for_rst_vf - checks to see if the PF has reset
39962583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
40062583d18SSepherosa Ziehau  *  @mbx_id: id of mailbox to check
40162583d18SSepherosa Ziehau  *
40262583d18SSepherosa Ziehau  *  returns TRUE if the PF has set the reset done bit or else FALSE
40362583d18SSepherosa Ziehau  **/
e1000_check_for_rst_vf(struct e1000_hw * hw,u16 E1000_UNUSEDARG mbx_id)404379ebbe7SSepherosa Ziehau static s32 e1000_check_for_rst_vf(struct e1000_hw *hw,
405379ebbe7SSepherosa Ziehau 				  u16 E1000_UNUSEDARG mbx_id)
40662583d18SSepherosa Ziehau {
40762583d18SSepherosa Ziehau 	s32 ret_val = -E1000_ERR_MBX;
40862583d18SSepherosa Ziehau 
40962583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_check_for_rst_vf");
41062583d18SSepherosa Ziehau 
41162583d18SSepherosa Ziehau 	if (!e1000_check_for_bit_vf(hw, (E1000_V2PMAILBOX_RSTD |
41262583d18SSepherosa Ziehau 					 E1000_V2PMAILBOX_RSTI))) {
41362583d18SSepherosa Ziehau 		ret_val = E1000_SUCCESS;
41462583d18SSepherosa Ziehau 		hw->mbx.stats.rsts++;
41562583d18SSepherosa Ziehau 	}
41662583d18SSepherosa Ziehau 
41762583d18SSepherosa Ziehau 	return ret_val;
41862583d18SSepherosa Ziehau }
41962583d18SSepherosa Ziehau 
42062583d18SSepherosa Ziehau /**
42162583d18SSepherosa Ziehau  *  e1000_obtain_mbx_lock_vf - obtain mailbox lock
42262583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
42362583d18SSepherosa Ziehau  *
42462583d18SSepherosa Ziehau  *  return SUCCESS if we obtained the mailbox lock
42562583d18SSepherosa Ziehau  **/
e1000_obtain_mbx_lock_vf(struct e1000_hw * hw)42662583d18SSepherosa Ziehau static s32 e1000_obtain_mbx_lock_vf(struct e1000_hw *hw)
42762583d18SSepherosa Ziehau {
42862583d18SSepherosa Ziehau 	s32 ret_val = -E1000_ERR_MBX;
429a40fda39SSepherosa Ziehau 	int count = 10;
43062583d18SSepherosa Ziehau 
43162583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_obtain_mbx_lock_vf");
43262583d18SSepherosa Ziehau 
433a40fda39SSepherosa Ziehau 	do {
43462583d18SSepherosa Ziehau 		/* Take ownership of the buffer */
43562583d18SSepherosa Ziehau 		E1000_WRITE_REG(hw, E1000_V2PMAILBOX(0), E1000_V2PMAILBOX_VFU);
43662583d18SSepherosa Ziehau 
43762583d18SSepherosa Ziehau 		/* reserve mailbox for vf use */
438a40fda39SSepherosa Ziehau 		if (e1000_read_v2p_mailbox(hw) & E1000_V2PMAILBOX_VFU) {
43962583d18SSepherosa Ziehau 			ret_val = E1000_SUCCESS;
440a40fda39SSepherosa Ziehau 			break;
441a40fda39SSepherosa Ziehau 		}
442a40fda39SSepherosa Ziehau 		usec_delay(1000);
443a40fda39SSepherosa Ziehau 	} while (count-- > 0);
44462583d18SSepherosa Ziehau 
44562583d18SSepherosa Ziehau 	return ret_val;
44662583d18SSepherosa Ziehau }
44762583d18SSepherosa Ziehau 
44862583d18SSepherosa Ziehau /**
44962583d18SSepherosa Ziehau  *  e1000_write_mbx_vf - Write a message to the mailbox
45062583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
45162583d18SSepherosa Ziehau  *  @msg: The message buffer
45262583d18SSepherosa Ziehau  *  @size: Length of buffer
45362583d18SSepherosa Ziehau  *  @mbx_id: id of mailbox to write
45462583d18SSepherosa Ziehau  *
45562583d18SSepherosa Ziehau  *  returns SUCCESS if it successfully copied message into the buffer
45662583d18SSepherosa Ziehau  **/
e1000_write_mbx_vf(struct e1000_hw * hw,u32 * msg,u16 size,u16 E1000_UNUSEDARG mbx_id)45762583d18SSepherosa Ziehau static s32 e1000_write_mbx_vf(struct e1000_hw *hw, u32 *msg, u16 size,
458379ebbe7SSepherosa Ziehau 			      u16 E1000_UNUSEDARG mbx_id)
45962583d18SSepherosa Ziehau {
46062583d18SSepherosa Ziehau 	s32 ret_val;
46162583d18SSepherosa Ziehau 	u16 i;
46262583d18SSepherosa Ziehau 
46362583d18SSepherosa Ziehau 
46462583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_write_mbx_vf");
46562583d18SSepherosa Ziehau 
46662583d18SSepherosa Ziehau 	/* lock the mailbox to prevent pf/vf race condition */
46762583d18SSepherosa Ziehau 	ret_val = e1000_obtain_mbx_lock_vf(hw);
46862583d18SSepherosa Ziehau 	if (ret_val)
46962583d18SSepherosa Ziehau 		goto out_no_write;
47062583d18SSepherosa Ziehau 
47162583d18SSepherosa Ziehau 	/* flush msg and acks as we are overwriting the message buffer */
47262583d18SSepherosa Ziehau 	e1000_check_for_msg_vf(hw, 0);
47362583d18SSepherosa Ziehau 	e1000_check_for_ack_vf(hw, 0);
47462583d18SSepherosa Ziehau 
47562583d18SSepherosa Ziehau 	/* copy the caller specified message to the mailbox memory buffer */
47662583d18SSepherosa Ziehau 	for (i = 0; i < size; i++)
47762583d18SSepherosa Ziehau 		E1000_WRITE_REG_ARRAY(hw, E1000_VMBMEM(0), i, msg[i]);
47862583d18SSepherosa Ziehau 
47962583d18SSepherosa Ziehau 	/* update stats */
48062583d18SSepherosa Ziehau 	hw->mbx.stats.msgs_tx++;
48162583d18SSepherosa Ziehau 
48262583d18SSepherosa Ziehau 	/* Drop VFU and interrupt the PF to tell it a message has been sent */
48362583d18SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_V2PMAILBOX(0), E1000_V2PMAILBOX_REQ);
48462583d18SSepherosa Ziehau 
48562583d18SSepherosa Ziehau out_no_write:
48662583d18SSepherosa Ziehau 	return ret_val;
48762583d18SSepherosa Ziehau }
48862583d18SSepherosa Ziehau 
48962583d18SSepherosa Ziehau /**
49062583d18SSepherosa Ziehau  *  e1000_read_mbx_vf - Reads a message from the inbox intended for vf
49162583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
49262583d18SSepherosa Ziehau  *  @msg: The message buffer
49362583d18SSepherosa Ziehau  *  @size: Length of buffer
49462583d18SSepherosa Ziehau  *  @mbx_id: id of mailbox to read
49562583d18SSepherosa Ziehau  *
49662583d18SSepherosa Ziehau  *  returns SUCCESS if it successfuly read message from buffer
49762583d18SSepherosa Ziehau  **/
e1000_read_mbx_vf(struct e1000_hw * hw,u32 * msg,u16 size,u16 E1000_UNUSEDARG mbx_id)49862583d18SSepherosa Ziehau static s32 e1000_read_mbx_vf(struct e1000_hw *hw, u32 *msg, u16 size,
499379ebbe7SSepherosa Ziehau 			     u16 E1000_UNUSEDARG mbx_id)
50062583d18SSepherosa Ziehau {
50162583d18SSepherosa Ziehau 	s32 ret_val = E1000_SUCCESS;
50262583d18SSepherosa Ziehau 	u16 i;
50362583d18SSepherosa Ziehau 
50462583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_read_mbx_vf");
50562583d18SSepherosa Ziehau 
50662583d18SSepherosa Ziehau 	/* lock the mailbox to prevent pf/vf race condition */
50762583d18SSepherosa Ziehau 	ret_val = e1000_obtain_mbx_lock_vf(hw);
50862583d18SSepherosa Ziehau 	if (ret_val)
50962583d18SSepherosa Ziehau 		goto out_no_read;
51062583d18SSepherosa Ziehau 
51162583d18SSepherosa Ziehau 	/* copy the message from the mailbox memory buffer */
51262583d18SSepherosa Ziehau 	for (i = 0; i < size; i++)
51362583d18SSepherosa Ziehau 		msg[i] = E1000_READ_REG_ARRAY(hw, E1000_VMBMEM(0), i);
51462583d18SSepherosa Ziehau 
51562583d18SSepherosa Ziehau 	/* Acknowledge receipt and release mailbox, then we're done */
51662583d18SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_V2PMAILBOX(0), E1000_V2PMAILBOX_ACK);
51762583d18SSepherosa Ziehau 
51862583d18SSepherosa Ziehau 	/* update stats */
51962583d18SSepherosa Ziehau 	hw->mbx.stats.msgs_rx++;
52062583d18SSepherosa Ziehau 
52162583d18SSepherosa Ziehau out_no_read:
52262583d18SSepherosa Ziehau 	return ret_val;
52362583d18SSepherosa Ziehau }
52462583d18SSepherosa Ziehau 
52562583d18SSepherosa Ziehau /**
52662583d18SSepherosa Ziehau  *  e1000_init_mbx_params_vf - set initial values for vf mailbox
52762583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
52862583d18SSepherosa Ziehau  *
52962583d18SSepherosa Ziehau  *  Initializes the hw->mbx struct to correct values for vf mailbox
53062583d18SSepherosa Ziehau  */
e1000_init_mbx_params_vf(struct e1000_hw * hw)53162583d18SSepherosa Ziehau s32 e1000_init_mbx_params_vf(struct e1000_hw *hw)
53262583d18SSepherosa Ziehau {
53362583d18SSepherosa Ziehau 	struct e1000_mbx_info *mbx = &hw->mbx;
53462583d18SSepherosa Ziehau 
53562583d18SSepherosa Ziehau 	/* start mailbox as timed out and let the reset_hw call set the timeout
53662583d18SSepherosa Ziehau 	 * value to begin communications */
53762583d18SSepherosa Ziehau 	mbx->timeout = 0;
53862583d18SSepherosa Ziehau 	mbx->usec_delay = E1000_VF_MBX_INIT_DELAY;
53962583d18SSepherosa Ziehau 
54062583d18SSepherosa Ziehau 	mbx->size = E1000_VFMAILBOX_SIZE;
54162583d18SSepherosa Ziehau 
54262583d18SSepherosa Ziehau 	mbx->ops.read = e1000_read_mbx_vf;
54362583d18SSepherosa Ziehau 	mbx->ops.write = e1000_write_mbx_vf;
54462583d18SSepherosa Ziehau 	mbx->ops.read_posted = e1000_read_posted_mbx;
54562583d18SSepherosa Ziehau 	mbx->ops.write_posted = e1000_write_posted_mbx;
54662583d18SSepherosa Ziehau 	mbx->ops.check_for_msg = e1000_check_for_msg_vf;
54762583d18SSepherosa Ziehau 	mbx->ops.check_for_ack = e1000_check_for_ack_vf;
54862583d18SSepherosa Ziehau 	mbx->ops.check_for_rst = e1000_check_for_rst_vf;
54962583d18SSepherosa Ziehau 
55062583d18SSepherosa Ziehau 	mbx->stats.msgs_tx = 0;
55162583d18SSepherosa Ziehau 	mbx->stats.msgs_rx = 0;
55262583d18SSepherosa Ziehau 	mbx->stats.reqs = 0;
55362583d18SSepherosa Ziehau 	mbx->stats.acks = 0;
55462583d18SSepherosa Ziehau 	mbx->stats.rsts = 0;
55562583d18SSepherosa Ziehau 
55662583d18SSepherosa Ziehau 	return E1000_SUCCESS;
55762583d18SSepherosa Ziehau }
55862583d18SSepherosa Ziehau 
e1000_check_for_bit_pf(struct e1000_hw * hw,u32 mask)55962583d18SSepherosa Ziehau static s32 e1000_check_for_bit_pf(struct e1000_hw *hw, u32 mask)
56062583d18SSepherosa Ziehau {
56162583d18SSepherosa Ziehau 	u32 mbvficr = E1000_READ_REG(hw, E1000_MBVFICR);
56262583d18SSepherosa Ziehau 	s32 ret_val = -E1000_ERR_MBX;
56362583d18SSepherosa Ziehau 
56462583d18SSepherosa Ziehau 	if (mbvficr & mask) {
56562583d18SSepherosa Ziehau 		ret_val = E1000_SUCCESS;
56662583d18SSepherosa Ziehau 		E1000_WRITE_REG(hw, E1000_MBVFICR, mask);
56762583d18SSepherosa Ziehau 	}
56862583d18SSepherosa Ziehau 
56962583d18SSepherosa Ziehau 	return ret_val;
57062583d18SSepherosa Ziehau }
57162583d18SSepherosa Ziehau 
57262583d18SSepherosa Ziehau /**
57362583d18SSepherosa Ziehau  *  e1000_check_for_msg_pf - checks to see if the VF has sent mail
57462583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
57562583d18SSepherosa Ziehau  *  @vf_number: the VF index
57662583d18SSepherosa Ziehau  *
57762583d18SSepherosa Ziehau  *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
57862583d18SSepherosa Ziehau  **/
e1000_check_for_msg_pf(struct e1000_hw * hw,u16 vf_number)57962583d18SSepherosa Ziehau static s32 e1000_check_for_msg_pf(struct e1000_hw *hw, u16 vf_number)
58062583d18SSepherosa Ziehau {
58162583d18SSepherosa Ziehau 	s32 ret_val = -E1000_ERR_MBX;
58262583d18SSepherosa Ziehau 
58362583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_check_for_msg_pf");
58462583d18SSepherosa Ziehau 
58562583d18SSepherosa Ziehau 	if (!e1000_check_for_bit_pf(hw, E1000_MBVFICR_VFREQ_VF1 << vf_number)) {
58662583d18SSepherosa Ziehau 		ret_val = E1000_SUCCESS;
58762583d18SSepherosa Ziehau 		hw->mbx.stats.reqs++;
58862583d18SSepherosa Ziehau 	}
58962583d18SSepherosa Ziehau 
59062583d18SSepherosa Ziehau 	return ret_val;
59162583d18SSepherosa Ziehau }
59262583d18SSepherosa Ziehau 
59362583d18SSepherosa Ziehau /**
59462583d18SSepherosa Ziehau  *  e1000_check_for_ack_pf - checks to see if the VF has ACKed
59562583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
59662583d18SSepherosa Ziehau  *  @vf_number: the VF index
59762583d18SSepherosa Ziehau  *
59862583d18SSepherosa Ziehau  *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
59962583d18SSepherosa Ziehau  **/
e1000_check_for_ack_pf(struct e1000_hw * hw,u16 vf_number)60062583d18SSepherosa Ziehau static s32 e1000_check_for_ack_pf(struct e1000_hw *hw, u16 vf_number)
60162583d18SSepherosa Ziehau {
60262583d18SSepherosa Ziehau 	s32 ret_val = -E1000_ERR_MBX;
60362583d18SSepherosa Ziehau 
60462583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_check_for_ack_pf");
60562583d18SSepherosa Ziehau 
60662583d18SSepherosa Ziehau 	if (!e1000_check_for_bit_pf(hw, E1000_MBVFICR_VFACK_VF1 << vf_number)) {
60762583d18SSepherosa Ziehau 		ret_val = E1000_SUCCESS;
60862583d18SSepherosa Ziehau 		hw->mbx.stats.acks++;
60962583d18SSepherosa Ziehau 	}
61062583d18SSepherosa Ziehau 
61162583d18SSepherosa Ziehau 	return ret_val;
61262583d18SSepherosa Ziehau }
61362583d18SSepherosa Ziehau 
61462583d18SSepherosa Ziehau /**
61562583d18SSepherosa Ziehau  *  e1000_check_for_rst_pf - checks to see if the VF has reset
61662583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
61762583d18SSepherosa Ziehau  *  @vf_number: the VF index
61862583d18SSepherosa Ziehau  *
61962583d18SSepherosa Ziehau  *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
62062583d18SSepherosa Ziehau  **/
e1000_check_for_rst_pf(struct e1000_hw * hw,u16 vf_number)62162583d18SSepherosa Ziehau static s32 e1000_check_for_rst_pf(struct e1000_hw *hw, u16 vf_number)
62262583d18SSepherosa Ziehau {
62362583d18SSepherosa Ziehau 	u32 vflre = E1000_READ_REG(hw, E1000_VFLRE);
62462583d18SSepherosa Ziehau 	s32 ret_val = -E1000_ERR_MBX;
62562583d18SSepherosa Ziehau 
62662583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_check_for_rst_pf");
62762583d18SSepherosa Ziehau 
62862583d18SSepherosa Ziehau 	if (vflre & (1 << vf_number)) {
62962583d18SSepherosa Ziehau 		ret_val = E1000_SUCCESS;
63062583d18SSepherosa Ziehau 		E1000_WRITE_REG(hw, E1000_VFLRE, (1 << vf_number));
63162583d18SSepherosa Ziehau 		hw->mbx.stats.rsts++;
63262583d18SSepherosa Ziehau 	}
63362583d18SSepherosa Ziehau 
63462583d18SSepherosa Ziehau 	return ret_val;
63562583d18SSepherosa Ziehau }
63662583d18SSepherosa Ziehau 
63762583d18SSepherosa Ziehau /**
63862583d18SSepherosa Ziehau  *  e1000_obtain_mbx_lock_pf - obtain mailbox lock
63962583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
64062583d18SSepherosa Ziehau  *  @vf_number: the VF index
64162583d18SSepherosa Ziehau  *
64262583d18SSepherosa Ziehau  *  return SUCCESS if we obtained the mailbox lock
64362583d18SSepherosa Ziehau  **/
e1000_obtain_mbx_lock_pf(struct e1000_hw * hw,u16 vf_number)64462583d18SSepherosa Ziehau static s32 e1000_obtain_mbx_lock_pf(struct e1000_hw *hw, u16 vf_number)
64562583d18SSepherosa Ziehau {
64662583d18SSepherosa Ziehau 	s32 ret_val = -E1000_ERR_MBX;
64762583d18SSepherosa Ziehau 	u32 p2v_mailbox;
648a40fda39SSepherosa Ziehau 	int count = 10;
64962583d18SSepherosa Ziehau 
65062583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_obtain_mbx_lock_pf");
65162583d18SSepherosa Ziehau 
652a40fda39SSepherosa Ziehau 	do {
65362583d18SSepherosa Ziehau 		/* Take ownership of the buffer */
654a40fda39SSepherosa Ziehau 		E1000_WRITE_REG(hw, E1000_P2VMAILBOX(vf_number),
655a40fda39SSepherosa Ziehau 				E1000_P2VMAILBOX_PFU);
65662583d18SSepherosa Ziehau 
657a40fda39SSepherosa Ziehau 		/* reserve mailbox for pf use */
65862583d18SSepherosa Ziehau 		p2v_mailbox = E1000_READ_REG(hw, E1000_P2VMAILBOX(vf_number));
659a40fda39SSepherosa Ziehau 		if (p2v_mailbox & E1000_P2VMAILBOX_PFU) {
66062583d18SSepherosa Ziehau 			ret_val = E1000_SUCCESS;
661a40fda39SSepherosa Ziehau 			break;
662a40fda39SSepherosa Ziehau 		}
663a40fda39SSepherosa Ziehau 		usec_delay(1000);
664a40fda39SSepherosa Ziehau 	} while (count-- > 0);
66562583d18SSepherosa Ziehau 
66662583d18SSepherosa Ziehau 	return ret_val;
667a40fda39SSepherosa Ziehau 
66862583d18SSepherosa Ziehau }
66962583d18SSepherosa Ziehau 
67062583d18SSepherosa Ziehau /**
67162583d18SSepherosa Ziehau  *  e1000_write_mbx_pf - Places a message in the mailbox
67262583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
67362583d18SSepherosa Ziehau  *  @msg: The message buffer
67462583d18SSepherosa Ziehau  *  @size: Length of buffer
67562583d18SSepherosa Ziehau  *  @vf_number: the VF index
67662583d18SSepherosa Ziehau  *
67762583d18SSepherosa Ziehau  *  returns SUCCESS if it successfully copied message into the buffer
67862583d18SSepherosa Ziehau  **/
e1000_write_mbx_pf(struct e1000_hw * hw,u32 * msg,u16 size,u16 vf_number)67962583d18SSepherosa Ziehau static s32 e1000_write_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size,
68062583d18SSepherosa Ziehau 			      u16 vf_number)
68162583d18SSepherosa Ziehau {
68262583d18SSepherosa Ziehau 	s32 ret_val;
68362583d18SSepherosa Ziehau 	u16 i;
68462583d18SSepherosa Ziehau 
68562583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_write_mbx_pf");
68662583d18SSepherosa Ziehau 
68762583d18SSepherosa Ziehau 	/* lock the mailbox to prevent pf/vf race condition */
68862583d18SSepherosa Ziehau 	ret_val = e1000_obtain_mbx_lock_pf(hw, vf_number);
68962583d18SSepherosa Ziehau 	if (ret_val)
69062583d18SSepherosa Ziehau 		goto out_no_write;
69162583d18SSepherosa Ziehau 
69262583d18SSepherosa Ziehau 	/* flush msg and acks as we are overwriting the message buffer */
69362583d18SSepherosa Ziehau 	e1000_check_for_msg_pf(hw, vf_number);
69462583d18SSepherosa Ziehau 	e1000_check_for_ack_pf(hw, vf_number);
69562583d18SSepherosa Ziehau 
69662583d18SSepherosa Ziehau 	/* copy the caller specified message to the mailbox memory buffer */
69762583d18SSepherosa Ziehau 	for (i = 0; i < size; i++)
69862583d18SSepherosa Ziehau 		E1000_WRITE_REG_ARRAY(hw, E1000_VMBMEM(vf_number), i, msg[i]);
69962583d18SSepherosa Ziehau 
70062583d18SSepherosa Ziehau 	/* Interrupt VF to tell it a message has been sent and release buffer*/
70162583d18SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_STS);
70262583d18SSepherosa Ziehau 
70362583d18SSepherosa Ziehau 	/* update stats */
70462583d18SSepherosa Ziehau 	hw->mbx.stats.msgs_tx++;
70562583d18SSepherosa Ziehau 
70662583d18SSepherosa Ziehau out_no_write:
70762583d18SSepherosa Ziehau 	return ret_val;
70862583d18SSepherosa Ziehau 
70962583d18SSepherosa Ziehau }
71062583d18SSepherosa Ziehau 
71162583d18SSepherosa Ziehau /**
71262583d18SSepherosa Ziehau  *  e1000_read_mbx_pf - Read a message from the mailbox
71362583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
71462583d18SSepherosa Ziehau  *  @msg: The message buffer
71562583d18SSepherosa Ziehau  *  @size: Length of buffer
71662583d18SSepherosa Ziehau  *  @vf_number: the VF index
71762583d18SSepherosa Ziehau  *
71862583d18SSepherosa Ziehau  *  This function copies a message from the mailbox buffer to the caller's
71962583d18SSepherosa Ziehau  *  memory buffer.  The presumption is that the caller knows that there was
72062583d18SSepherosa Ziehau  *  a message due to a VF request so no polling for message is needed.
72162583d18SSepherosa Ziehau  **/
e1000_read_mbx_pf(struct e1000_hw * hw,u32 * msg,u16 size,u16 vf_number)72262583d18SSepherosa Ziehau static s32 e1000_read_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size,
72362583d18SSepherosa Ziehau 			     u16 vf_number)
72462583d18SSepherosa Ziehau {
72562583d18SSepherosa Ziehau 	s32 ret_val;
72662583d18SSepherosa Ziehau 	u16 i;
72762583d18SSepherosa Ziehau 
72862583d18SSepherosa Ziehau 	DEBUGFUNC("e1000_read_mbx_pf");
72962583d18SSepherosa Ziehau 
73062583d18SSepherosa Ziehau 	/* lock the mailbox to prevent pf/vf race condition */
73162583d18SSepherosa Ziehau 	ret_val = e1000_obtain_mbx_lock_pf(hw, vf_number);
73262583d18SSepherosa Ziehau 	if (ret_val)
73362583d18SSepherosa Ziehau 		goto out_no_read;
73462583d18SSepherosa Ziehau 
73562583d18SSepherosa Ziehau 	/* copy the message to the mailbox memory buffer */
73662583d18SSepherosa Ziehau 	for (i = 0; i < size; i++)
73762583d18SSepherosa Ziehau 		msg[i] = E1000_READ_REG_ARRAY(hw, E1000_VMBMEM(vf_number), i);
73862583d18SSepherosa Ziehau 
73962583d18SSepherosa Ziehau 	/* Acknowledge the message and release buffer */
74062583d18SSepherosa Ziehau 	E1000_WRITE_REG(hw, E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_ACK);
74162583d18SSepherosa Ziehau 
74262583d18SSepherosa Ziehau 	/* update stats */
74362583d18SSepherosa Ziehau 	hw->mbx.stats.msgs_rx++;
74462583d18SSepherosa Ziehau 
74562583d18SSepherosa Ziehau out_no_read:
74662583d18SSepherosa Ziehau 	return ret_val;
74762583d18SSepherosa Ziehau }
74862583d18SSepherosa Ziehau 
74962583d18SSepherosa Ziehau /**
75062583d18SSepherosa Ziehau  *  e1000_init_mbx_params_pf - set initial values for pf mailbox
75162583d18SSepherosa Ziehau  *  @hw: pointer to the HW structure
75262583d18SSepherosa Ziehau  *
75362583d18SSepherosa Ziehau  *  Initializes the hw->mbx struct to correct values for pf mailbox
75462583d18SSepherosa Ziehau  */
e1000_init_mbx_params_pf(struct e1000_hw * hw)75562583d18SSepherosa Ziehau s32 e1000_init_mbx_params_pf(struct e1000_hw *hw)
75662583d18SSepherosa Ziehau {
75762583d18SSepherosa Ziehau 	struct e1000_mbx_info *mbx = &hw->mbx;
75862583d18SSepherosa Ziehau 
75962583d18SSepherosa Ziehau 	switch (hw->mac.type) {
76062583d18SSepherosa Ziehau 	case e1000_82576:
76162583d18SSepherosa Ziehau 	case e1000_i350:
762379ebbe7SSepherosa Ziehau 	case e1000_i354:
76362583d18SSepherosa Ziehau 		mbx->timeout = 0;
76462583d18SSepherosa Ziehau 		mbx->usec_delay = 0;
76562583d18SSepherosa Ziehau 
76662583d18SSepherosa Ziehau 		mbx->size = E1000_VFMAILBOX_SIZE;
76762583d18SSepherosa Ziehau 
76862583d18SSepherosa Ziehau 		mbx->ops.read = e1000_read_mbx_pf;
76962583d18SSepherosa Ziehau 		mbx->ops.write = e1000_write_mbx_pf;
77062583d18SSepherosa Ziehau 		mbx->ops.read_posted = e1000_read_posted_mbx;
77162583d18SSepherosa Ziehau 		mbx->ops.write_posted = e1000_write_posted_mbx;
77262583d18SSepherosa Ziehau 		mbx->ops.check_for_msg = e1000_check_for_msg_pf;
77362583d18SSepherosa Ziehau 		mbx->ops.check_for_ack = e1000_check_for_ack_pf;
77462583d18SSepherosa Ziehau 		mbx->ops.check_for_rst = e1000_check_for_rst_pf;
77562583d18SSepherosa Ziehau 
77662583d18SSepherosa Ziehau 		mbx->stats.msgs_tx = 0;
77762583d18SSepherosa Ziehau 		mbx->stats.msgs_rx = 0;
77862583d18SSepherosa Ziehau 		mbx->stats.reqs = 0;
77962583d18SSepherosa Ziehau 		mbx->stats.acks = 0;
78062583d18SSepherosa Ziehau 		mbx->stats.rsts = 0;
78162583d18SSepherosa Ziehau 	default:
78262583d18SSepherosa Ziehau 		return E1000_SUCCESS;
78362583d18SSepherosa Ziehau 	}
78462583d18SSepherosa Ziehau }
78562583d18SSepherosa Ziehau 
786