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