175eba5b6SRobert Mustacchi /******************************************************************************
275eba5b6SRobert Mustacchi
3*7c5988f9SRobert Mustacchi Copyright (c) 2001-2015, Intel Corporation
475eba5b6SRobert Mustacchi All rights reserved.
575eba5b6SRobert Mustacchi
675eba5b6SRobert Mustacchi Redistribution and use in source and binary forms, with or without
775eba5b6SRobert Mustacchi modification, are permitted provided that the following conditions are met:
875eba5b6SRobert Mustacchi
975eba5b6SRobert Mustacchi 1. Redistributions of source code must retain the above copyright notice,
1075eba5b6SRobert Mustacchi this list of conditions and the following disclaimer.
1175eba5b6SRobert Mustacchi
1275eba5b6SRobert Mustacchi 2. Redistributions in binary form must reproduce the above copyright
1375eba5b6SRobert Mustacchi notice, this list of conditions and the following disclaimer in the
1475eba5b6SRobert Mustacchi documentation and/or other materials provided with the distribution.
1575eba5b6SRobert Mustacchi
1675eba5b6SRobert Mustacchi 3. Neither the name of the Intel Corporation nor the names of its
1775eba5b6SRobert Mustacchi contributors may be used to endorse or promote products derived from
1875eba5b6SRobert Mustacchi this software without specific prior written permission.
1975eba5b6SRobert Mustacchi
2075eba5b6SRobert Mustacchi THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2175eba5b6SRobert Mustacchi AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2275eba5b6SRobert Mustacchi IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2375eba5b6SRobert Mustacchi ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
2475eba5b6SRobert Mustacchi LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2575eba5b6SRobert Mustacchi CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2675eba5b6SRobert Mustacchi SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2775eba5b6SRobert Mustacchi INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2875eba5b6SRobert Mustacchi CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2975eba5b6SRobert Mustacchi ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3075eba5b6SRobert Mustacchi POSSIBILITY OF SUCH DAMAGE.
3175eba5b6SRobert Mustacchi
3275eba5b6SRobert Mustacchi ******************************************************************************/
3375eba5b6SRobert Mustacchi /*$FreeBSD$*/
3475eba5b6SRobert Mustacchi
3575eba5b6SRobert Mustacchi #include "e1000_mbx.h"
3675eba5b6SRobert Mustacchi
3775eba5b6SRobert Mustacchi /**
3875eba5b6SRobert Mustacchi * e1000_null_mbx_check_for_flag - No-op function, return 0
3975eba5b6SRobert Mustacchi * @hw: pointer to the HW structure
4075eba5b6SRobert Mustacchi **/
e1000_null_mbx_check_for_flag(struct e1000_hw E1000_UNUSEDARG * hw,u16 E1000_UNUSEDARG mbx_id)41c124a83eSRobert Mustacchi static s32 e1000_null_mbx_check_for_flag(struct e1000_hw E1000_UNUSEDARG *hw,
42c124a83eSRobert Mustacchi u16 E1000_UNUSEDARG mbx_id)
4375eba5b6SRobert Mustacchi {
4475eba5b6SRobert Mustacchi DEBUGFUNC("e1000_null_mbx_check_flag");
4575eba5b6SRobert Mustacchi
4675eba5b6SRobert Mustacchi return E1000_SUCCESS;
4775eba5b6SRobert Mustacchi }
4875eba5b6SRobert Mustacchi
4975eba5b6SRobert Mustacchi /**
5075eba5b6SRobert Mustacchi * e1000_null_mbx_transact - No-op function, return 0
5175eba5b6SRobert Mustacchi * @hw: pointer to the HW structure
5275eba5b6SRobert Mustacchi **/
e1000_null_mbx_transact(struct e1000_hw E1000_UNUSEDARG * hw,u32 E1000_UNUSEDARG * msg,u16 E1000_UNUSEDARG size,u16 E1000_UNUSEDARG mbx_id)53c124a83eSRobert Mustacchi static s32 e1000_null_mbx_transact(struct e1000_hw E1000_UNUSEDARG *hw,
54c124a83eSRobert Mustacchi u32 E1000_UNUSEDARG *msg,
55c124a83eSRobert Mustacchi u16 E1000_UNUSEDARG size,
56c124a83eSRobert Mustacchi u16 E1000_UNUSEDARG mbx_id)
5775eba5b6SRobert Mustacchi {
5875eba5b6SRobert Mustacchi DEBUGFUNC("e1000_null_mbx_rw_msg");
5975eba5b6SRobert Mustacchi
6075eba5b6SRobert Mustacchi return E1000_SUCCESS;
6175eba5b6SRobert Mustacchi }
6275eba5b6SRobert Mustacchi
6375eba5b6SRobert Mustacchi /**
6475eba5b6SRobert Mustacchi * e1000_read_mbx - Reads a message from the mailbox
6575eba5b6SRobert Mustacchi * @hw: pointer to the HW structure
6675eba5b6SRobert Mustacchi * @msg: The message buffer
6775eba5b6SRobert Mustacchi * @size: Length of buffer
6875eba5b6SRobert Mustacchi * @mbx_id: id of mailbox to read
6975eba5b6SRobert Mustacchi *
7075eba5b6SRobert Mustacchi * returns SUCCESS if it successfuly read message from buffer
7175eba5b6SRobert Mustacchi **/
e1000_read_mbx(struct e1000_hw * hw,u32 * msg,u16 size,u16 mbx_id)7275eba5b6SRobert Mustacchi s32 e1000_read_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
7375eba5b6SRobert Mustacchi {
7475eba5b6SRobert Mustacchi struct e1000_mbx_info *mbx = &hw->mbx;
7575eba5b6SRobert Mustacchi s32 ret_val = -E1000_ERR_MBX;
7675eba5b6SRobert Mustacchi
7775eba5b6SRobert Mustacchi DEBUGFUNC("e1000_read_mbx");
7875eba5b6SRobert Mustacchi
7975eba5b6SRobert Mustacchi /* limit read to size of mailbox */
8075eba5b6SRobert Mustacchi if (size > mbx->size)
8175eba5b6SRobert Mustacchi size = mbx->size;
8275eba5b6SRobert Mustacchi
8375eba5b6SRobert Mustacchi if (mbx->ops.read)
8475eba5b6SRobert Mustacchi ret_val = mbx->ops.read(hw, msg, size, mbx_id);
8575eba5b6SRobert Mustacchi
8675eba5b6SRobert Mustacchi return ret_val;
8775eba5b6SRobert Mustacchi }
8875eba5b6SRobert Mustacchi
8975eba5b6SRobert Mustacchi /**
9075eba5b6SRobert Mustacchi * e1000_write_mbx - Write a message to the mailbox
9175eba5b6SRobert Mustacchi * @hw: pointer to the HW structure
9275eba5b6SRobert Mustacchi * @msg: The message buffer
9375eba5b6SRobert Mustacchi * @size: Length of buffer
9475eba5b6SRobert Mustacchi * @mbx_id: id of mailbox to write
9575eba5b6SRobert Mustacchi *
9675eba5b6SRobert Mustacchi * returns SUCCESS if it successfully copied message into the buffer
9775eba5b6SRobert Mustacchi **/
e1000_write_mbx(struct e1000_hw * hw,u32 * msg,u16 size,u16 mbx_id)9875eba5b6SRobert Mustacchi s32 e1000_write_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
9975eba5b6SRobert Mustacchi {
10075eba5b6SRobert Mustacchi struct e1000_mbx_info *mbx = &hw->mbx;
10175eba5b6SRobert Mustacchi s32 ret_val = E1000_SUCCESS;
10275eba5b6SRobert Mustacchi
10375eba5b6SRobert Mustacchi DEBUGFUNC("e1000_write_mbx");
10475eba5b6SRobert Mustacchi
10575eba5b6SRobert Mustacchi if (size > mbx->size)
10675eba5b6SRobert Mustacchi ret_val = -E1000_ERR_MBX;
10775eba5b6SRobert Mustacchi
10875eba5b6SRobert Mustacchi else if (mbx->ops.write)
10975eba5b6SRobert Mustacchi ret_val = mbx->ops.write(hw, msg, size, mbx_id);
11075eba5b6SRobert Mustacchi
11175eba5b6SRobert Mustacchi return ret_val;
11275eba5b6SRobert Mustacchi }
11375eba5b6SRobert Mustacchi
11475eba5b6SRobert Mustacchi /**
11575eba5b6SRobert Mustacchi * e1000_check_for_msg - checks to see if someone sent us mail
11675eba5b6SRobert Mustacchi * @hw: pointer to the HW structure
11775eba5b6SRobert Mustacchi * @mbx_id: id of mailbox to check
11875eba5b6SRobert Mustacchi *
11975eba5b6SRobert Mustacchi * returns SUCCESS if the Status bit was found or else ERR_MBX
12075eba5b6SRobert Mustacchi **/
e1000_check_for_msg(struct e1000_hw * hw,u16 mbx_id)12175eba5b6SRobert Mustacchi s32 e1000_check_for_msg(struct e1000_hw *hw, u16 mbx_id)
12275eba5b6SRobert Mustacchi {
12375eba5b6SRobert Mustacchi struct e1000_mbx_info *mbx = &hw->mbx;
12475eba5b6SRobert Mustacchi s32 ret_val = -E1000_ERR_MBX;
12575eba5b6SRobert Mustacchi
12675eba5b6SRobert Mustacchi DEBUGFUNC("e1000_check_for_msg");
12775eba5b6SRobert Mustacchi
12875eba5b6SRobert Mustacchi if (mbx->ops.check_for_msg)
12975eba5b6SRobert Mustacchi ret_val = mbx->ops.check_for_msg(hw, mbx_id);
13075eba5b6SRobert Mustacchi
13175eba5b6SRobert Mustacchi return ret_val;
13275eba5b6SRobert Mustacchi }
13375eba5b6SRobert Mustacchi
13475eba5b6SRobert Mustacchi /**
13575eba5b6SRobert Mustacchi * e1000_check_for_ack - checks to see if someone sent us ACK
13675eba5b6SRobert Mustacchi * @hw: pointer to the HW structure
13775eba5b6SRobert Mustacchi * @mbx_id: id of mailbox to check
13875eba5b6SRobert Mustacchi *
13975eba5b6SRobert Mustacchi * returns SUCCESS if the Status bit was found or else ERR_MBX
14075eba5b6SRobert Mustacchi **/
e1000_check_for_ack(struct e1000_hw * hw,u16 mbx_id)14175eba5b6SRobert Mustacchi s32 e1000_check_for_ack(struct e1000_hw *hw, u16 mbx_id)
14275eba5b6SRobert Mustacchi {
14375eba5b6SRobert Mustacchi struct e1000_mbx_info *mbx = &hw->mbx;
14475eba5b6SRobert Mustacchi s32 ret_val = -E1000_ERR_MBX;
14575eba5b6SRobert Mustacchi
14675eba5b6SRobert Mustacchi DEBUGFUNC("e1000_check_for_ack");
14775eba5b6SRobert Mustacchi
14875eba5b6SRobert Mustacchi if (mbx->ops.check_for_ack)
14975eba5b6SRobert Mustacchi ret_val = mbx->ops.check_for_ack(hw, mbx_id);
15075eba5b6SRobert Mustacchi
15175eba5b6SRobert Mustacchi return ret_val;
15275eba5b6SRobert Mustacchi }
15375eba5b6SRobert Mustacchi
15475eba5b6SRobert Mustacchi /**
15575eba5b6SRobert Mustacchi * e1000_check_for_rst - checks to see if other side has reset
15675eba5b6SRobert Mustacchi * @hw: pointer to the HW structure
15775eba5b6SRobert Mustacchi * @mbx_id: id of mailbox to check
15875eba5b6SRobert Mustacchi *
15975eba5b6SRobert Mustacchi * returns SUCCESS if the Status bit was found or else ERR_MBX
16075eba5b6SRobert Mustacchi **/
e1000_check_for_rst(struct e1000_hw * hw,u16 mbx_id)16175eba5b6SRobert Mustacchi s32 e1000_check_for_rst(struct e1000_hw *hw, u16 mbx_id)
16275eba5b6SRobert Mustacchi {
16375eba5b6SRobert Mustacchi struct e1000_mbx_info *mbx = &hw->mbx;
16475eba5b6SRobert Mustacchi s32 ret_val = -E1000_ERR_MBX;
16575eba5b6SRobert Mustacchi
16675eba5b6SRobert Mustacchi DEBUGFUNC("e1000_check_for_rst");
16775eba5b6SRobert Mustacchi
16875eba5b6SRobert Mustacchi if (mbx->ops.check_for_rst)
16975eba5b6SRobert Mustacchi ret_val = mbx->ops.check_for_rst(hw, mbx_id);
17075eba5b6SRobert Mustacchi
17175eba5b6SRobert Mustacchi return ret_val;
17275eba5b6SRobert Mustacchi }
17375eba5b6SRobert Mustacchi
17475eba5b6SRobert Mustacchi /**
17575eba5b6SRobert Mustacchi * e1000_poll_for_msg - Wait for message notification
17675eba5b6SRobert Mustacchi * @hw: pointer to the HW structure
17775eba5b6SRobert Mustacchi * @mbx_id: id of mailbox to write
17875eba5b6SRobert Mustacchi *
17975eba5b6SRobert Mustacchi * returns SUCCESS if it successfully received a message notification
18075eba5b6SRobert Mustacchi **/
e1000_poll_for_msg(struct e1000_hw * hw,u16 mbx_id)18175eba5b6SRobert Mustacchi static s32 e1000_poll_for_msg(struct e1000_hw *hw, u16 mbx_id)
18275eba5b6SRobert Mustacchi {
18375eba5b6SRobert Mustacchi struct e1000_mbx_info *mbx = &hw->mbx;
18475eba5b6SRobert Mustacchi int countdown = mbx->timeout;
18575eba5b6SRobert Mustacchi
18675eba5b6SRobert Mustacchi DEBUGFUNC("e1000_poll_for_msg");
18775eba5b6SRobert Mustacchi
18875eba5b6SRobert Mustacchi if (!countdown || !mbx->ops.check_for_msg)
18975eba5b6SRobert Mustacchi goto out;
19075eba5b6SRobert Mustacchi
19175eba5b6SRobert Mustacchi while (countdown && mbx->ops.check_for_msg(hw, mbx_id)) {
19275eba5b6SRobert Mustacchi countdown--;
19375eba5b6SRobert Mustacchi if (!countdown)
19475eba5b6SRobert Mustacchi break;
19575eba5b6SRobert Mustacchi usec_delay(mbx->usec_delay);
19675eba5b6SRobert Mustacchi }
19775eba5b6SRobert Mustacchi
19875eba5b6SRobert Mustacchi /* if we failed, all future posted messages fail until reset */
19975eba5b6SRobert Mustacchi if (!countdown)
20075eba5b6SRobert Mustacchi mbx->timeout = 0;
20175eba5b6SRobert Mustacchi out:
20275eba5b6SRobert Mustacchi return countdown ? E1000_SUCCESS : -E1000_ERR_MBX;
20375eba5b6SRobert Mustacchi }
20475eba5b6SRobert Mustacchi
20575eba5b6SRobert Mustacchi /**
20675eba5b6SRobert Mustacchi * e1000_poll_for_ack - Wait for message acknowledgement
20775eba5b6SRobert Mustacchi * @hw: pointer to the HW structure
20875eba5b6SRobert Mustacchi * @mbx_id: id of mailbox to write
20975eba5b6SRobert Mustacchi *
21075eba5b6SRobert Mustacchi * returns SUCCESS if it successfully received a message acknowledgement
21175eba5b6SRobert Mustacchi **/
e1000_poll_for_ack(struct e1000_hw * hw,u16 mbx_id)21275eba5b6SRobert Mustacchi static s32 e1000_poll_for_ack(struct e1000_hw *hw, u16 mbx_id)
21375eba5b6SRobert Mustacchi {
21475eba5b6SRobert Mustacchi struct e1000_mbx_info *mbx = &hw->mbx;
21575eba5b6SRobert Mustacchi int countdown = mbx->timeout;
21675eba5b6SRobert Mustacchi
21775eba5b6SRobert Mustacchi DEBUGFUNC("e1000_poll_for_ack");
21875eba5b6SRobert Mustacchi
21975eba5b6SRobert Mustacchi if (!countdown || !mbx->ops.check_for_ack)
22075eba5b6SRobert Mustacchi goto out;
22175eba5b6SRobert Mustacchi
22275eba5b6SRobert Mustacchi while (countdown && mbx->ops.check_for_ack(hw, mbx_id)) {
22375eba5b6SRobert Mustacchi countdown--;
22475eba5b6SRobert Mustacchi if (!countdown)
22575eba5b6SRobert Mustacchi break;
22675eba5b6SRobert Mustacchi usec_delay(mbx->usec_delay);
22775eba5b6SRobert Mustacchi }
22875eba5b6SRobert Mustacchi
22975eba5b6SRobert Mustacchi /* if we failed, all future posted messages fail until reset */
23075eba5b6SRobert Mustacchi if (!countdown)
23175eba5b6SRobert Mustacchi mbx->timeout = 0;
23275eba5b6SRobert Mustacchi out:
23375eba5b6SRobert Mustacchi return countdown ? E1000_SUCCESS : -E1000_ERR_MBX;
23475eba5b6SRobert Mustacchi }
23575eba5b6SRobert Mustacchi
23675eba5b6SRobert Mustacchi /**
23775eba5b6SRobert Mustacchi * e1000_read_posted_mbx - Wait for message notification and receive message
23875eba5b6SRobert Mustacchi * @hw: pointer to the HW structure
23975eba5b6SRobert Mustacchi * @msg: The message buffer
24075eba5b6SRobert Mustacchi * @size: Length of buffer
24175eba5b6SRobert Mustacchi * @mbx_id: id of mailbox to write
24275eba5b6SRobert Mustacchi *
24375eba5b6SRobert Mustacchi * returns SUCCESS if it successfully received a message notification and
24475eba5b6SRobert Mustacchi * copied it into the receive buffer.
24575eba5b6SRobert Mustacchi **/
e1000_read_posted_mbx(struct e1000_hw * hw,u32 * msg,u16 size,u16 mbx_id)24675eba5b6SRobert Mustacchi s32 e1000_read_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
24775eba5b6SRobert Mustacchi {
24875eba5b6SRobert Mustacchi struct e1000_mbx_info *mbx = &hw->mbx;
24975eba5b6SRobert Mustacchi s32 ret_val = -E1000_ERR_MBX;
25075eba5b6SRobert Mustacchi
25175eba5b6SRobert Mustacchi DEBUGFUNC("e1000_read_posted_mbx");
25275eba5b6SRobert Mustacchi
25375eba5b6SRobert Mustacchi if (!mbx->ops.read)
25475eba5b6SRobert Mustacchi goto out;
25575eba5b6SRobert Mustacchi
25675eba5b6SRobert Mustacchi ret_val = e1000_poll_for_msg(hw, mbx_id);
25775eba5b6SRobert Mustacchi
25875eba5b6SRobert Mustacchi /* if ack received read message, otherwise we timed out */
25975eba5b6SRobert Mustacchi if (!ret_val)
26075eba5b6SRobert Mustacchi ret_val = mbx->ops.read(hw, msg, size, mbx_id);
26175eba5b6SRobert Mustacchi out:
26275eba5b6SRobert Mustacchi return ret_val;
26375eba5b6SRobert Mustacchi }
26475eba5b6SRobert Mustacchi
26575eba5b6SRobert Mustacchi /**
26675eba5b6SRobert Mustacchi * e1000_write_posted_mbx - Write a message to the mailbox, wait for ack
26775eba5b6SRobert Mustacchi * @hw: pointer to the HW structure
26875eba5b6SRobert Mustacchi * @msg: The message buffer
26975eba5b6SRobert Mustacchi * @size: Length of buffer
27075eba5b6SRobert Mustacchi * @mbx_id: id of mailbox to write
27175eba5b6SRobert Mustacchi *
27275eba5b6SRobert Mustacchi * returns SUCCESS if it successfully copied message into the buffer and
27375eba5b6SRobert Mustacchi * received an ack to that message within delay * timeout period
27475eba5b6SRobert Mustacchi **/
e1000_write_posted_mbx(struct e1000_hw * hw,u32 * msg,u16 size,u16 mbx_id)27575eba5b6SRobert Mustacchi s32 e1000_write_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
27675eba5b6SRobert Mustacchi {
27775eba5b6SRobert Mustacchi struct e1000_mbx_info *mbx = &hw->mbx;
27875eba5b6SRobert Mustacchi s32 ret_val = -E1000_ERR_MBX;
27975eba5b6SRobert Mustacchi
28075eba5b6SRobert Mustacchi DEBUGFUNC("e1000_write_posted_mbx");
28175eba5b6SRobert Mustacchi
28275eba5b6SRobert Mustacchi /* exit if either we can't write or there isn't a defined timeout */
28375eba5b6SRobert Mustacchi if (!mbx->ops.write || !mbx->timeout)
28475eba5b6SRobert Mustacchi goto out;
28575eba5b6SRobert Mustacchi
28675eba5b6SRobert Mustacchi /* send msg */
28775eba5b6SRobert Mustacchi ret_val = mbx->ops.write(hw, msg, size, mbx_id);
28875eba5b6SRobert Mustacchi
28975eba5b6SRobert Mustacchi /* if msg sent wait until we receive an ack */
29075eba5b6SRobert Mustacchi if (!ret_val)
29175eba5b6SRobert Mustacchi ret_val = e1000_poll_for_ack(hw, mbx_id);
29275eba5b6SRobert Mustacchi out:
29375eba5b6SRobert Mustacchi return ret_val;
29475eba5b6SRobert Mustacchi }
29575eba5b6SRobert Mustacchi
29675eba5b6SRobert Mustacchi /**
29775eba5b6SRobert Mustacchi * e1000_init_mbx_ops_generic - Initialize mbx function pointers
29875eba5b6SRobert Mustacchi * @hw: pointer to the HW structure
29975eba5b6SRobert Mustacchi *
30075eba5b6SRobert Mustacchi * Sets the function pointers to no-op functions
30175eba5b6SRobert Mustacchi **/
e1000_init_mbx_ops_generic(struct e1000_hw * hw)30275eba5b6SRobert Mustacchi void e1000_init_mbx_ops_generic(struct e1000_hw *hw)
30375eba5b6SRobert Mustacchi {
30475eba5b6SRobert Mustacchi struct e1000_mbx_info *mbx = &hw->mbx;
30575eba5b6SRobert Mustacchi mbx->ops.init_params = e1000_null_ops_generic;
30675eba5b6SRobert Mustacchi mbx->ops.read = e1000_null_mbx_transact;
30775eba5b6SRobert Mustacchi mbx->ops.write = e1000_null_mbx_transact;
30875eba5b6SRobert Mustacchi mbx->ops.check_for_msg = e1000_null_mbx_check_for_flag;
30975eba5b6SRobert Mustacchi mbx->ops.check_for_ack = e1000_null_mbx_check_for_flag;
31075eba5b6SRobert Mustacchi mbx->ops.check_for_rst = e1000_null_mbx_check_for_flag;
31175eba5b6SRobert Mustacchi mbx->ops.read_posted = e1000_read_posted_mbx;
31275eba5b6SRobert Mustacchi mbx->ops.write_posted = e1000_write_posted_mbx;
31375eba5b6SRobert Mustacchi }
31475eba5b6SRobert Mustacchi
31575eba5b6SRobert Mustacchi /**
31675eba5b6SRobert Mustacchi * e1000_read_v2p_mailbox - read v2p mailbox
31775eba5b6SRobert Mustacchi * @hw: pointer to the HW structure
31875eba5b6SRobert Mustacchi *
31975eba5b6SRobert Mustacchi * This function is used to read the v2p mailbox without losing the read to
32075eba5b6SRobert Mustacchi * clear status bits.
32175eba5b6SRobert Mustacchi **/
e1000_read_v2p_mailbox(struct e1000_hw * hw)32275eba5b6SRobert Mustacchi static u32 e1000_read_v2p_mailbox(struct e1000_hw *hw)
32375eba5b6SRobert Mustacchi {
32475eba5b6SRobert Mustacchi u32 v2p_mailbox = E1000_READ_REG(hw, E1000_V2PMAILBOX(0));
32575eba5b6SRobert Mustacchi
32675eba5b6SRobert Mustacchi v2p_mailbox |= hw->dev_spec.vf.v2p_mailbox;
32775eba5b6SRobert Mustacchi hw->dev_spec.vf.v2p_mailbox |= v2p_mailbox & E1000_V2PMAILBOX_R2C_BITS;
32875eba5b6SRobert Mustacchi
32975eba5b6SRobert Mustacchi return v2p_mailbox;
33075eba5b6SRobert Mustacchi }
33175eba5b6SRobert Mustacchi
33275eba5b6SRobert Mustacchi /**
33375eba5b6SRobert Mustacchi * e1000_check_for_bit_vf - Determine if a status bit was set
33475eba5b6SRobert Mustacchi * @hw: pointer to the HW structure
33575eba5b6SRobert Mustacchi * @mask: bitmask for bits to be tested and cleared
33675eba5b6SRobert Mustacchi *
33775eba5b6SRobert Mustacchi * This function is used to check for the read to clear bits within
33875eba5b6SRobert Mustacchi * the V2P mailbox.
33975eba5b6SRobert Mustacchi **/
e1000_check_for_bit_vf(struct e1000_hw * hw,u32 mask)34075eba5b6SRobert Mustacchi static s32 e1000_check_for_bit_vf(struct e1000_hw *hw, u32 mask)
34175eba5b6SRobert Mustacchi {
34275eba5b6SRobert Mustacchi u32 v2p_mailbox = e1000_read_v2p_mailbox(hw);
34375eba5b6SRobert Mustacchi s32 ret_val = -E1000_ERR_MBX;
34475eba5b6SRobert Mustacchi
34575eba5b6SRobert Mustacchi if (v2p_mailbox & mask)
34675eba5b6SRobert Mustacchi ret_val = E1000_SUCCESS;
34775eba5b6SRobert Mustacchi
34875eba5b6SRobert Mustacchi hw->dev_spec.vf.v2p_mailbox &= ~mask;
34975eba5b6SRobert Mustacchi
35075eba5b6SRobert Mustacchi return ret_val;
35175eba5b6SRobert Mustacchi }
35275eba5b6SRobert Mustacchi
35375eba5b6SRobert Mustacchi /**
35475eba5b6SRobert Mustacchi * e1000_check_for_msg_vf - checks to see if the PF has sent mail
35575eba5b6SRobert Mustacchi * @hw: pointer to the HW structure
35675eba5b6SRobert Mustacchi * @mbx_id: id of mailbox to check
35775eba5b6SRobert Mustacchi *
35875eba5b6SRobert Mustacchi * returns SUCCESS if the PF has set the Status bit or else ERR_MBX
35975eba5b6SRobert Mustacchi **/
e1000_check_for_msg_vf(struct e1000_hw * hw,u16 E1000_UNUSEDARG mbx_id)360c124a83eSRobert Mustacchi static s32 e1000_check_for_msg_vf(struct e1000_hw *hw,
361c124a83eSRobert Mustacchi u16 E1000_UNUSEDARG mbx_id)
36275eba5b6SRobert Mustacchi {
36375eba5b6SRobert Mustacchi s32 ret_val = -E1000_ERR_MBX;
36475eba5b6SRobert Mustacchi
36575eba5b6SRobert Mustacchi DEBUGFUNC("e1000_check_for_msg_vf");
36675eba5b6SRobert Mustacchi
36775eba5b6SRobert Mustacchi if (!e1000_check_for_bit_vf(hw, E1000_V2PMAILBOX_PFSTS)) {
36875eba5b6SRobert Mustacchi ret_val = E1000_SUCCESS;
36975eba5b6SRobert Mustacchi hw->mbx.stats.reqs++;
37075eba5b6SRobert Mustacchi }
37175eba5b6SRobert Mustacchi
37275eba5b6SRobert Mustacchi return ret_val;
37375eba5b6SRobert Mustacchi }
37475eba5b6SRobert Mustacchi
37575eba5b6SRobert Mustacchi /**
37675eba5b6SRobert Mustacchi * e1000_check_for_ack_vf - checks to see if the PF has ACK'd
37775eba5b6SRobert Mustacchi * @hw: pointer to the HW structure
37875eba5b6SRobert Mustacchi * @mbx_id: id of mailbox to check
37975eba5b6SRobert Mustacchi *
38075eba5b6SRobert Mustacchi * returns SUCCESS if the PF has set the ACK bit or else ERR_MBX
38175eba5b6SRobert Mustacchi **/
e1000_check_for_ack_vf(struct e1000_hw * hw,u16 E1000_UNUSEDARG mbx_id)382c124a83eSRobert Mustacchi static s32 e1000_check_for_ack_vf(struct e1000_hw *hw,
383c124a83eSRobert Mustacchi u16 E1000_UNUSEDARG mbx_id)
38475eba5b6SRobert Mustacchi {
38575eba5b6SRobert Mustacchi s32 ret_val = -E1000_ERR_MBX;
38675eba5b6SRobert Mustacchi
38775eba5b6SRobert Mustacchi DEBUGFUNC("e1000_check_for_ack_vf");
38875eba5b6SRobert Mustacchi
38975eba5b6SRobert Mustacchi if (!e1000_check_for_bit_vf(hw, E1000_V2PMAILBOX_PFACK)) {
39075eba5b6SRobert Mustacchi ret_val = E1000_SUCCESS;
39175eba5b6SRobert Mustacchi hw->mbx.stats.acks++;
39275eba5b6SRobert Mustacchi }
39375eba5b6SRobert Mustacchi
39475eba5b6SRobert Mustacchi return ret_val;
39575eba5b6SRobert Mustacchi }
39675eba5b6SRobert Mustacchi
39775eba5b6SRobert Mustacchi /**
39875eba5b6SRobert Mustacchi * e1000_check_for_rst_vf - checks to see if the PF has reset
39975eba5b6SRobert Mustacchi * @hw: pointer to the HW structure
40075eba5b6SRobert Mustacchi * @mbx_id: id of mailbox to check
40175eba5b6SRobert Mustacchi *
40275eba5b6SRobert Mustacchi * returns TRUE if the PF has set the reset done bit or else FALSE
40375eba5b6SRobert Mustacchi **/
e1000_check_for_rst_vf(struct e1000_hw * hw,u16 E1000_UNUSEDARG mbx_id)404c124a83eSRobert Mustacchi static s32 e1000_check_for_rst_vf(struct e1000_hw *hw,
405c124a83eSRobert Mustacchi u16 E1000_UNUSEDARG mbx_id)
40675eba5b6SRobert Mustacchi {
40775eba5b6SRobert Mustacchi s32 ret_val = -E1000_ERR_MBX;
40875eba5b6SRobert Mustacchi
40975eba5b6SRobert Mustacchi DEBUGFUNC("e1000_check_for_rst_vf");
41075eba5b6SRobert Mustacchi
41175eba5b6SRobert Mustacchi if (!e1000_check_for_bit_vf(hw, (E1000_V2PMAILBOX_RSTD |
41275eba5b6SRobert Mustacchi E1000_V2PMAILBOX_RSTI))) {
41375eba5b6SRobert Mustacchi ret_val = E1000_SUCCESS;
41475eba5b6SRobert Mustacchi hw->mbx.stats.rsts++;
41575eba5b6SRobert Mustacchi }
41675eba5b6SRobert Mustacchi
41775eba5b6SRobert Mustacchi return ret_val;
41875eba5b6SRobert Mustacchi }
41975eba5b6SRobert Mustacchi
42075eba5b6SRobert Mustacchi /**
42175eba5b6SRobert Mustacchi * e1000_obtain_mbx_lock_vf - obtain mailbox lock
42275eba5b6SRobert Mustacchi * @hw: pointer to the HW structure
42375eba5b6SRobert Mustacchi *
42475eba5b6SRobert Mustacchi * return SUCCESS if we obtained the mailbox lock
42575eba5b6SRobert Mustacchi **/
e1000_obtain_mbx_lock_vf(struct e1000_hw * hw)42675eba5b6SRobert Mustacchi static s32 e1000_obtain_mbx_lock_vf(struct e1000_hw *hw)
42775eba5b6SRobert Mustacchi {
42875eba5b6SRobert Mustacchi s32 ret_val = -E1000_ERR_MBX;
429*7c5988f9SRobert Mustacchi int count = 10;
43075eba5b6SRobert Mustacchi
43175eba5b6SRobert Mustacchi DEBUGFUNC("e1000_obtain_mbx_lock_vf");
43275eba5b6SRobert Mustacchi
433*7c5988f9SRobert Mustacchi do {
43475eba5b6SRobert Mustacchi /* Take ownership of the buffer */
43575eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_V2PMAILBOX(0), E1000_V2PMAILBOX_VFU);
43675eba5b6SRobert Mustacchi
43775eba5b6SRobert Mustacchi /* reserve mailbox for vf use */
438*7c5988f9SRobert Mustacchi if (e1000_read_v2p_mailbox(hw) & E1000_V2PMAILBOX_VFU) {
43975eba5b6SRobert Mustacchi ret_val = E1000_SUCCESS;
440*7c5988f9SRobert Mustacchi break;
441*7c5988f9SRobert Mustacchi }
442*7c5988f9SRobert Mustacchi usec_delay(1000);
443*7c5988f9SRobert Mustacchi } while (count-- > 0);
44475eba5b6SRobert Mustacchi
44575eba5b6SRobert Mustacchi return ret_val;
44675eba5b6SRobert Mustacchi }
44775eba5b6SRobert Mustacchi
44875eba5b6SRobert Mustacchi /**
44975eba5b6SRobert Mustacchi * e1000_write_mbx_vf - Write a message to the mailbox
45075eba5b6SRobert Mustacchi * @hw: pointer to the HW structure
45175eba5b6SRobert Mustacchi * @msg: The message buffer
45275eba5b6SRobert Mustacchi * @size: Length of buffer
45375eba5b6SRobert Mustacchi * @mbx_id: id of mailbox to write
45475eba5b6SRobert Mustacchi *
45575eba5b6SRobert Mustacchi * returns SUCCESS if it successfully copied message into the buffer
45675eba5b6SRobert Mustacchi **/
e1000_write_mbx_vf(struct e1000_hw * hw,u32 * msg,u16 size,u16 E1000_UNUSEDARG mbx_id)45775eba5b6SRobert Mustacchi static s32 e1000_write_mbx_vf(struct e1000_hw *hw, u32 *msg, u16 size,
458c124a83eSRobert Mustacchi u16 E1000_UNUSEDARG mbx_id)
45975eba5b6SRobert Mustacchi {
46075eba5b6SRobert Mustacchi s32 ret_val;
46175eba5b6SRobert Mustacchi u16 i;
46275eba5b6SRobert Mustacchi
46375eba5b6SRobert Mustacchi
46475eba5b6SRobert Mustacchi DEBUGFUNC("e1000_write_mbx_vf");
46575eba5b6SRobert Mustacchi
46675eba5b6SRobert Mustacchi /* lock the mailbox to prevent pf/vf race condition */
46775eba5b6SRobert Mustacchi ret_val = e1000_obtain_mbx_lock_vf(hw);
46875eba5b6SRobert Mustacchi if (ret_val)
46975eba5b6SRobert Mustacchi goto out_no_write;
47075eba5b6SRobert Mustacchi
47175eba5b6SRobert Mustacchi /* flush msg and acks as we are overwriting the message buffer */
47275eba5b6SRobert Mustacchi e1000_check_for_msg_vf(hw, 0);
47375eba5b6SRobert Mustacchi e1000_check_for_ack_vf(hw, 0);
47475eba5b6SRobert Mustacchi
47575eba5b6SRobert Mustacchi /* copy the caller specified message to the mailbox memory buffer */
47675eba5b6SRobert Mustacchi for (i = 0; i < size; i++)
47775eba5b6SRobert Mustacchi E1000_WRITE_REG_ARRAY(hw, E1000_VMBMEM(0), i, msg[i]);
47875eba5b6SRobert Mustacchi
47975eba5b6SRobert Mustacchi /* update stats */
48075eba5b6SRobert Mustacchi hw->mbx.stats.msgs_tx++;
48175eba5b6SRobert Mustacchi
48275eba5b6SRobert Mustacchi /* Drop VFU and interrupt the PF to tell it a message has been sent */
48375eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_V2PMAILBOX(0), E1000_V2PMAILBOX_REQ);
48475eba5b6SRobert Mustacchi
48575eba5b6SRobert Mustacchi out_no_write:
48675eba5b6SRobert Mustacchi return ret_val;
48775eba5b6SRobert Mustacchi }
48875eba5b6SRobert Mustacchi
48975eba5b6SRobert Mustacchi /**
49075eba5b6SRobert Mustacchi * e1000_read_mbx_vf - Reads a message from the inbox intended for vf
49175eba5b6SRobert Mustacchi * @hw: pointer to the HW structure
49275eba5b6SRobert Mustacchi * @msg: The message buffer
49375eba5b6SRobert Mustacchi * @size: Length of buffer
49475eba5b6SRobert Mustacchi * @mbx_id: id of mailbox to read
49575eba5b6SRobert Mustacchi *
49675eba5b6SRobert Mustacchi * returns SUCCESS if it successfuly read message from buffer
49775eba5b6SRobert Mustacchi **/
e1000_read_mbx_vf(struct e1000_hw * hw,u32 * msg,u16 size,u16 E1000_UNUSEDARG mbx_id)49875eba5b6SRobert Mustacchi static s32 e1000_read_mbx_vf(struct e1000_hw *hw, u32 *msg, u16 size,
499c124a83eSRobert Mustacchi u16 E1000_UNUSEDARG mbx_id)
50075eba5b6SRobert Mustacchi {
50175eba5b6SRobert Mustacchi s32 ret_val = E1000_SUCCESS;
50275eba5b6SRobert Mustacchi u16 i;
50375eba5b6SRobert Mustacchi
50475eba5b6SRobert Mustacchi DEBUGFUNC("e1000_read_mbx_vf");
50575eba5b6SRobert Mustacchi
50675eba5b6SRobert Mustacchi /* lock the mailbox to prevent pf/vf race condition */
50775eba5b6SRobert Mustacchi ret_val = e1000_obtain_mbx_lock_vf(hw);
50875eba5b6SRobert Mustacchi if (ret_val)
50975eba5b6SRobert Mustacchi goto out_no_read;
51075eba5b6SRobert Mustacchi
51175eba5b6SRobert Mustacchi /* copy the message from the mailbox memory buffer */
51275eba5b6SRobert Mustacchi for (i = 0; i < size; i++)
51375eba5b6SRobert Mustacchi msg[i] = E1000_READ_REG_ARRAY(hw, E1000_VMBMEM(0), i);
51475eba5b6SRobert Mustacchi
51575eba5b6SRobert Mustacchi /* Acknowledge receipt and release mailbox, then we're done */
51675eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_V2PMAILBOX(0), E1000_V2PMAILBOX_ACK);
51775eba5b6SRobert Mustacchi
51875eba5b6SRobert Mustacchi /* update stats */
51975eba5b6SRobert Mustacchi hw->mbx.stats.msgs_rx++;
52075eba5b6SRobert Mustacchi
52175eba5b6SRobert Mustacchi out_no_read:
52275eba5b6SRobert Mustacchi return ret_val;
52375eba5b6SRobert Mustacchi }
52475eba5b6SRobert Mustacchi
52575eba5b6SRobert Mustacchi /**
52675eba5b6SRobert Mustacchi * e1000_init_mbx_params_vf - set initial values for vf mailbox
52775eba5b6SRobert Mustacchi * @hw: pointer to the HW structure
52875eba5b6SRobert Mustacchi *
52975eba5b6SRobert Mustacchi * Initializes the hw->mbx struct to correct values for vf mailbox
53075eba5b6SRobert Mustacchi */
e1000_init_mbx_params_vf(struct e1000_hw * hw)53175eba5b6SRobert Mustacchi s32 e1000_init_mbx_params_vf(struct e1000_hw *hw)
53275eba5b6SRobert Mustacchi {
53375eba5b6SRobert Mustacchi struct e1000_mbx_info *mbx = &hw->mbx;
53475eba5b6SRobert Mustacchi
53575eba5b6SRobert Mustacchi /* start mailbox as timed out and let the reset_hw call set the timeout
53675eba5b6SRobert Mustacchi * value to begin communications */
53775eba5b6SRobert Mustacchi mbx->timeout = 0;
53875eba5b6SRobert Mustacchi mbx->usec_delay = E1000_VF_MBX_INIT_DELAY;
53975eba5b6SRobert Mustacchi
54075eba5b6SRobert Mustacchi mbx->size = E1000_VFMAILBOX_SIZE;
54175eba5b6SRobert Mustacchi
54275eba5b6SRobert Mustacchi mbx->ops.read = e1000_read_mbx_vf;
54375eba5b6SRobert Mustacchi mbx->ops.write = e1000_write_mbx_vf;
54475eba5b6SRobert Mustacchi mbx->ops.read_posted = e1000_read_posted_mbx;
54575eba5b6SRobert Mustacchi mbx->ops.write_posted = e1000_write_posted_mbx;
54675eba5b6SRobert Mustacchi mbx->ops.check_for_msg = e1000_check_for_msg_vf;
54775eba5b6SRobert Mustacchi mbx->ops.check_for_ack = e1000_check_for_ack_vf;
54875eba5b6SRobert Mustacchi mbx->ops.check_for_rst = e1000_check_for_rst_vf;
54975eba5b6SRobert Mustacchi
55075eba5b6SRobert Mustacchi mbx->stats.msgs_tx = 0;
55175eba5b6SRobert Mustacchi mbx->stats.msgs_rx = 0;
55275eba5b6SRobert Mustacchi mbx->stats.reqs = 0;
55375eba5b6SRobert Mustacchi mbx->stats.acks = 0;
55475eba5b6SRobert Mustacchi mbx->stats.rsts = 0;
55575eba5b6SRobert Mustacchi
55675eba5b6SRobert Mustacchi return E1000_SUCCESS;
55775eba5b6SRobert Mustacchi }
55875eba5b6SRobert Mustacchi
e1000_check_for_bit_pf(struct e1000_hw * hw,u32 mask)55975eba5b6SRobert Mustacchi static s32 e1000_check_for_bit_pf(struct e1000_hw *hw, u32 mask)
56075eba5b6SRobert Mustacchi {
56175eba5b6SRobert Mustacchi u32 mbvficr = E1000_READ_REG(hw, E1000_MBVFICR);
56275eba5b6SRobert Mustacchi s32 ret_val = -E1000_ERR_MBX;
56375eba5b6SRobert Mustacchi
56475eba5b6SRobert Mustacchi if (mbvficr & mask) {
56575eba5b6SRobert Mustacchi ret_val = E1000_SUCCESS;
56675eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_MBVFICR, mask);
56775eba5b6SRobert Mustacchi }
56875eba5b6SRobert Mustacchi
56975eba5b6SRobert Mustacchi return ret_val;
57075eba5b6SRobert Mustacchi }
57175eba5b6SRobert Mustacchi
57275eba5b6SRobert Mustacchi /**
57375eba5b6SRobert Mustacchi * e1000_check_for_msg_pf - checks to see if the VF has sent mail
57475eba5b6SRobert Mustacchi * @hw: pointer to the HW structure
57575eba5b6SRobert Mustacchi * @vf_number: the VF index
57675eba5b6SRobert Mustacchi *
57775eba5b6SRobert Mustacchi * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
57875eba5b6SRobert Mustacchi **/
e1000_check_for_msg_pf(struct e1000_hw * hw,u16 vf_number)57975eba5b6SRobert Mustacchi static s32 e1000_check_for_msg_pf(struct e1000_hw *hw, u16 vf_number)
58075eba5b6SRobert Mustacchi {
58175eba5b6SRobert Mustacchi s32 ret_val = -E1000_ERR_MBX;
58275eba5b6SRobert Mustacchi
58375eba5b6SRobert Mustacchi DEBUGFUNC("e1000_check_for_msg_pf");
58475eba5b6SRobert Mustacchi
58575eba5b6SRobert Mustacchi if (!e1000_check_for_bit_pf(hw, E1000_MBVFICR_VFREQ_VF1 << vf_number)) {
58675eba5b6SRobert Mustacchi ret_val = E1000_SUCCESS;
58775eba5b6SRobert Mustacchi hw->mbx.stats.reqs++;
58875eba5b6SRobert Mustacchi }
58975eba5b6SRobert Mustacchi
59075eba5b6SRobert Mustacchi return ret_val;
59175eba5b6SRobert Mustacchi }
59275eba5b6SRobert Mustacchi
59375eba5b6SRobert Mustacchi /**
59475eba5b6SRobert Mustacchi * e1000_check_for_ack_pf - checks to see if the VF has ACKed
59575eba5b6SRobert Mustacchi * @hw: pointer to the HW structure
59675eba5b6SRobert Mustacchi * @vf_number: the VF index
59775eba5b6SRobert Mustacchi *
59875eba5b6SRobert Mustacchi * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
59975eba5b6SRobert Mustacchi **/
e1000_check_for_ack_pf(struct e1000_hw * hw,u16 vf_number)60075eba5b6SRobert Mustacchi static s32 e1000_check_for_ack_pf(struct e1000_hw *hw, u16 vf_number)
60175eba5b6SRobert Mustacchi {
60275eba5b6SRobert Mustacchi s32 ret_val = -E1000_ERR_MBX;
60375eba5b6SRobert Mustacchi
60475eba5b6SRobert Mustacchi DEBUGFUNC("e1000_check_for_ack_pf");
60575eba5b6SRobert Mustacchi
60675eba5b6SRobert Mustacchi if (!e1000_check_for_bit_pf(hw, E1000_MBVFICR_VFACK_VF1 << vf_number)) {
60775eba5b6SRobert Mustacchi ret_val = E1000_SUCCESS;
60875eba5b6SRobert Mustacchi hw->mbx.stats.acks++;
60975eba5b6SRobert Mustacchi }
61075eba5b6SRobert Mustacchi
61175eba5b6SRobert Mustacchi return ret_val;
61275eba5b6SRobert Mustacchi }
61375eba5b6SRobert Mustacchi
61475eba5b6SRobert Mustacchi /**
61575eba5b6SRobert Mustacchi * e1000_check_for_rst_pf - checks to see if the VF has reset
61675eba5b6SRobert Mustacchi * @hw: pointer to the HW structure
61775eba5b6SRobert Mustacchi * @vf_number: the VF index
61875eba5b6SRobert Mustacchi *
61975eba5b6SRobert Mustacchi * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
62075eba5b6SRobert Mustacchi **/
e1000_check_for_rst_pf(struct e1000_hw * hw,u16 vf_number)62175eba5b6SRobert Mustacchi static s32 e1000_check_for_rst_pf(struct e1000_hw *hw, u16 vf_number)
62275eba5b6SRobert Mustacchi {
62375eba5b6SRobert Mustacchi u32 vflre = E1000_READ_REG(hw, E1000_VFLRE);
62475eba5b6SRobert Mustacchi s32 ret_val = -E1000_ERR_MBX;
62575eba5b6SRobert Mustacchi
62675eba5b6SRobert Mustacchi DEBUGFUNC("e1000_check_for_rst_pf");
62775eba5b6SRobert Mustacchi
62875eba5b6SRobert Mustacchi if (vflre & (1 << vf_number)) {
62975eba5b6SRobert Mustacchi ret_val = E1000_SUCCESS;
63075eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_VFLRE, (1 << vf_number));
63175eba5b6SRobert Mustacchi hw->mbx.stats.rsts++;
63275eba5b6SRobert Mustacchi }
63375eba5b6SRobert Mustacchi
63475eba5b6SRobert Mustacchi return ret_val;
63575eba5b6SRobert Mustacchi }
63675eba5b6SRobert Mustacchi
63775eba5b6SRobert Mustacchi /**
63875eba5b6SRobert Mustacchi * e1000_obtain_mbx_lock_pf - obtain mailbox lock
63975eba5b6SRobert Mustacchi * @hw: pointer to the HW structure
64075eba5b6SRobert Mustacchi * @vf_number: the VF index
64175eba5b6SRobert Mustacchi *
64275eba5b6SRobert Mustacchi * return SUCCESS if we obtained the mailbox lock
64375eba5b6SRobert Mustacchi **/
e1000_obtain_mbx_lock_pf(struct e1000_hw * hw,u16 vf_number)64475eba5b6SRobert Mustacchi static s32 e1000_obtain_mbx_lock_pf(struct e1000_hw *hw, u16 vf_number)
64575eba5b6SRobert Mustacchi {
64675eba5b6SRobert Mustacchi s32 ret_val = -E1000_ERR_MBX;
64775eba5b6SRobert Mustacchi u32 p2v_mailbox;
648*7c5988f9SRobert Mustacchi int count = 10;
64975eba5b6SRobert Mustacchi
65075eba5b6SRobert Mustacchi DEBUGFUNC("e1000_obtain_mbx_lock_pf");
65175eba5b6SRobert Mustacchi
652*7c5988f9SRobert Mustacchi do {
65375eba5b6SRobert Mustacchi /* Take ownership of the buffer */
654*7c5988f9SRobert Mustacchi E1000_WRITE_REG(hw, E1000_P2VMAILBOX(vf_number),
655*7c5988f9SRobert Mustacchi E1000_P2VMAILBOX_PFU);
65675eba5b6SRobert Mustacchi
657*7c5988f9SRobert Mustacchi /* reserve mailbox for pf use */
65875eba5b6SRobert Mustacchi p2v_mailbox = E1000_READ_REG(hw, E1000_P2VMAILBOX(vf_number));
659*7c5988f9SRobert Mustacchi if (p2v_mailbox & E1000_P2VMAILBOX_PFU) {
66075eba5b6SRobert Mustacchi ret_val = E1000_SUCCESS;
661*7c5988f9SRobert Mustacchi break;
662*7c5988f9SRobert Mustacchi }
663*7c5988f9SRobert Mustacchi usec_delay(1000);
664*7c5988f9SRobert Mustacchi } while (count-- > 0);
66575eba5b6SRobert Mustacchi
66675eba5b6SRobert Mustacchi return ret_val;
667*7c5988f9SRobert Mustacchi
66875eba5b6SRobert Mustacchi }
66975eba5b6SRobert Mustacchi
67075eba5b6SRobert Mustacchi /**
67175eba5b6SRobert Mustacchi * e1000_write_mbx_pf - Places a message in the mailbox
67275eba5b6SRobert Mustacchi * @hw: pointer to the HW structure
67375eba5b6SRobert Mustacchi * @msg: The message buffer
67475eba5b6SRobert Mustacchi * @size: Length of buffer
67575eba5b6SRobert Mustacchi * @vf_number: the VF index
67675eba5b6SRobert Mustacchi *
67775eba5b6SRobert Mustacchi * returns SUCCESS if it successfully copied message into the buffer
67875eba5b6SRobert Mustacchi **/
e1000_write_mbx_pf(struct e1000_hw * hw,u32 * msg,u16 size,u16 vf_number)67975eba5b6SRobert Mustacchi static s32 e1000_write_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size,
68075eba5b6SRobert Mustacchi u16 vf_number)
68175eba5b6SRobert Mustacchi {
68275eba5b6SRobert Mustacchi s32 ret_val;
68375eba5b6SRobert Mustacchi u16 i;
68475eba5b6SRobert Mustacchi
68575eba5b6SRobert Mustacchi DEBUGFUNC("e1000_write_mbx_pf");
68675eba5b6SRobert Mustacchi
68775eba5b6SRobert Mustacchi /* lock the mailbox to prevent pf/vf race condition */
68875eba5b6SRobert Mustacchi ret_val = e1000_obtain_mbx_lock_pf(hw, vf_number);
68975eba5b6SRobert Mustacchi if (ret_val)
69075eba5b6SRobert Mustacchi goto out_no_write;
69175eba5b6SRobert Mustacchi
69275eba5b6SRobert Mustacchi /* flush msg and acks as we are overwriting the message buffer */
69375eba5b6SRobert Mustacchi e1000_check_for_msg_pf(hw, vf_number);
69475eba5b6SRobert Mustacchi e1000_check_for_ack_pf(hw, vf_number);
69575eba5b6SRobert Mustacchi
69675eba5b6SRobert Mustacchi /* copy the caller specified message to the mailbox memory buffer */
69775eba5b6SRobert Mustacchi for (i = 0; i < size; i++)
69875eba5b6SRobert Mustacchi E1000_WRITE_REG_ARRAY(hw, E1000_VMBMEM(vf_number), i, msg[i]);
69975eba5b6SRobert Mustacchi
70075eba5b6SRobert Mustacchi /* Interrupt VF to tell it a message has been sent and release buffer*/
70175eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_STS);
70275eba5b6SRobert Mustacchi
70375eba5b6SRobert Mustacchi /* update stats */
70475eba5b6SRobert Mustacchi hw->mbx.stats.msgs_tx++;
70575eba5b6SRobert Mustacchi
70675eba5b6SRobert Mustacchi out_no_write:
70775eba5b6SRobert Mustacchi return ret_val;
70875eba5b6SRobert Mustacchi
70975eba5b6SRobert Mustacchi }
71075eba5b6SRobert Mustacchi
71175eba5b6SRobert Mustacchi /**
71275eba5b6SRobert Mustacchi * e1000_read_mbx_pf - Read a message from the mailbox
71375eba5b6SRobert Mustacchi * @hw: pointer to the HW structure
71475eba5b6SRobert Mustacchi * @msg: The message buffer
71575eba5b6SRobert Mustacchi * @size: Length of buffer
71675eba5b6SRobert Mustacchi * @vf_number: the VF index
71775eba5b6SRobert Mustacchi *
71875eba5b6SRobert Mustacchi * This function copies a message from the mailbox buffer to the caller's
71975eba5b6SRobert Mustacchi * memory buffer. The presumption is that the caller knows that there was
72075eba5b6SRobert Mustacchi * a message due to a VF request so no polling for message is needed.
72175eba5b6SRobert Mustacchi **/
e1000_read_mbx_pf(struct e1000_hw * hw,u32 * msg,u16 size,u16 vf_number)72275eba5b6SRobert Mustacchi static s32 e1000_read_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size,
72375eba5b6SRobert Mustacchi u16 vf_number)
72475eba5b6SRobert Mustacchi {
72575eba5b6SRobert Mustacchi s32 ret_val;
72675eba5b6SRobert Mustacchi u16 i;
72775eba5b6SRobert Mustacchi
72875eba5b6SRobert Mustacchi DEBUGFUNC("e1000_read_mbx_pf");
72975eba5b6SRobert Mustacchi
73075eba5b6SRobert Mustacchi /* lock the mailbox to prevent pf/vf race condition */
73175eba5b6SRobert Mustacchi ret_val = e1000_obtain_mbx_lock_pf(hw, vf_number);
73275eba5b6SRobert Mustacchi if (ret_val)
73375eba5b6SRobert Mustacchi goto out_no_read;
73475eba5b6SRobert Mustacchi
73575eba5b6SRobert Mustacchi /* copy the message to the mailbox memory buffer */
73675eba5b6SRobert Mustacchi for (i = 0; i < size; i++)
73775eba5b6SRobert Mustacchi msg[i] = E1000_READ_REG_ARRAY(hw, E1000_VMBMEM(vf_number), i);
73875eba5b6SRobert Mustacchi
73975eba5b6SRobert Mustacchi /* Acknowledge the message and release buffer */
74075eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_ACK);
74175eba5b6SRobert Mustacchi
74275eba5b6SRobert Mustacchi /* update stats */
74375eba5b6SRobert Mustacchi hw->mbx.stats.msgs_rx++;
74475eba5b6SRobert Mustacchi
74575eba5b6SRobert Mustacchi out_no_read:
74675eba5b6SRobert Mustacchi return ret_val;
74775eba5b6SRobert Mustacchi }
74875eba5b6SRobert Mustacchi
74975eba5b6SRobert Mustacchi /**
75075eba5b6SRobert Mustacchi * e1000_init_mbx_params_pf - set initial values for pf mailbox
75175eba5b6SRobert Mustacchi * @hw: pointer to the HW structure
75275eba5b6SRobert Mustacchi *
75375eba5b6SRobert Mustacchi * Initializes the hw->mbx struct to correct values for pf mailbox
75475eba5b6SRobert Mustacchi */
e1000_init_mbx_params_pf(struct e1000_hw * hw)75575eba5b6SRobert Mustacchi s32 e1000_init_mbx_params_pf(struct e1000_hw *hw)
75675eba5b6SRobert Mustacchi {
75775eba5b6SRobert Mustacchi struct e1000_mbx_info *mbx = &hw->mbx;
75875eba5b6SRobert Mustacchi
75975eba5b6SRobert Mustacchi switch (hw->mac.type) {
76075eba5b6SRobert Mustacchi case e1000_82576:
76175eba5b6SRobert Mustacchi case e1000_i350:
762c124a83eSRobert Mustacchi case e1000_i354:
76375eba5b6SRobert Mustacchi mbx->timeout = 0;
76475eba5b6SRobert Mustacchi mbx->usec_delay = 0;
76575eba5b6SRobert Mustacchi
76675eba5b6SRobert Mustacchi mbx->size = E1000_VFMAILBOX_SIZE;
76775eba5b6SRobert Mustacchi
76875eba5b6SRobert Mustacchi mbx->ops.read = e1000_read_mbx_pf;
76975eba5b6SRobert Mustacchi mbx->ops.write = e1000_write_mbx_pf;
77075eba5b6SRobert Mustacchi mbx->ops.read_posted = e1000_read_posted_mbx;
77175eba5b6SRobert Mustacchi mbx->ops.write_posted = e1000_write_posted_mbx;
77275eba5b6SRobert Mustacchi mbx->ops.check_for_msg = e1000_check_for_msg_pf;
77375eba5b6SRobert Mustacchi mbx->ops.check_for_ack = e1000_check_for_ack_pf;
77475eba5b6SRobert Mustacchi mbx->ops.check_for_rst = e1000_check_for_rst_pf;
77575eba5b6SRobert Mustacchi
77675eba5b6SRobert Mustacchi mbx->stats.msgs_tx = 0;
77775eba5b6SRobert Mustacchi mbx->stats.msgs_rx = 0;
77875eba5b6SRobert Mustacchi mbx->stats.reqs = 0;
77975eba5b6SRobert Mustacchi mbx->stats.acks = 0;
78075eba5b6SRobert Mustacchi mbx->stats.rsts = 0;
78175eba5b6SRobert Mustacchi default:
78275eba5b6SRobert Mustacchi return E1000_SUCCESS;
78375eba5b6SRobert Mustacchi }
78475eba5b6SRobert Mustacchi }
78575eba5b6SRobert Mustacchi
786