xref: /freebsd-src/sys/dev/e1000/e1000_mbx.c (revision 71625ec9ad2a9bc8c09784fbd23b759830e0ee5f)
1b8270585SJack F Vogel /******************************************************************************
27282444bSPedro F. Giffuni   SPDX-License-Identifier: BSD-3-Clause
3b8270585SJack F Vogel 
4702cac6cSKevin Bowling   Copyright (c) 2001-2020, Intel Corporation
5b8270585SJack F Vogel   All rights reserved.
6b8270585SJack F Vogel 
7b8270585SJack F Vogel   Redistribution and use in source and binary forms, with or without
8b8270585SJack F Vogel   modification, are permitted provided that the following conditions are met:
9b8270585SJack F Vogel 
10b8270585SJack F Vogel    1. Redistributions of source code must retain the above copyright notice,
11b8270585SJack F Vogel       this list of conditions and the following disclaimer.
12b8270585SJack F Vogel 
13b8270585SJack F Vogel    2. Redistributions in binary form must reproduce the above copyright
14b8270585SJack F Vogel       notice, this list of conditions and the following disclaimer in the
15b8270585SJack F Vogel       documentation and/or other materials provided with the distribution.
16b8270585SJack F Vogel 
17b8270585SJack F Vogel    3. Neither the name of the Intel Corporation nor the names of its
18b8270585SJack F Vogel       contributors may be used to endorse or promote products derived from
19b8270585SJack F Vogel       this software without specific prior written permission.
20b8270585SJack F Vogel 
21b8270585SJack F Vogel   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22b8270585SJack F Vogel   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23b8270585SJack F Vogel   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24b8270585SJack F Vogel   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25b8270585SJack F Vogel   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26b8270585SJack F Vogel   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27b8270585SJack F Vogel   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28b8270585SJack F Vogel   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29b8270585SJack F Vogel   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30b8270585SJack F Vogel   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31b8270585SJack F Vogel   POSSIBILITY OF SUCH DAMAGE.
32b8270585SJack F Vogel 
33b8270585SJack F Vogel ******************************************************************************/
34b8270585SJack F Vogel 
35b8270585SJack F Vogel #include "e1000_mbx.h"
36b8270585SJack F Vogel 
37b8270585SJack F Vogel /**
38b8270585SJack F Vogel  *  e1000_null_mbx_check_for_flag - No-op function, return 0
39b8270585SJack F Vogel  *  @hw: pointer to the HW structure
405b426b3eSGuinan Sun  *  @mbx_id: id of mailbox to read
41b8270585SJack F Vogel  **/
e1000_null_mbx_check_for_flag(struct e1000_hw E1000_UNUSEDARG * hw,u16 E1000_UNUSEDARG mbx_id)428cc64f1eSJack F Vogel static s32 e1000_null_mbx_check_for_flag(struct e1000_hw E1000_UNUSEDARG *hw,
438cc64f1eSJack F Vogel 					 u16 E1000_UNUSEDARG mbx_id)
44b8270585SJack F Vogel {
45b8270585SJack F Vogel 	DEBUGFUNC("e1000_null_mbx_check_flag");
46b8270585SJack F Vogel 
47b8270585SJack F Vogel 	return E1000_SUCCESS;
48b8270585SJack F Vogel }
49b8270585SJack F Vogel 
50b8270585SJack F Vogel /**
51b8270585SJack F Vogel  *  e1000_null_mbx_transact - No-op function, return 0
52b8270585SJack F Vogel  *  @hw: pointer to the HW structure
535b426b3eSGuinan Sun  *  @msg: The message buffer
545b426b3eSGuinan Sun  *  @size: Length of buffer
555b426b3eSGuinan Sun  *  @mbx_id: id of mailbox to read
56b8270585SJack F Vogel  **/
e1000_null_mbx_transact(struct e1000_hw E1000_UNUSEDARG * hw,u32 E1000_UNUSEDARG * msg,u16 E1000_UNUSEDARG size,u16 E1000_UNUSEDARG mbx_id)578cc64f1eSJack F Vogel static s32 e1000_null_mbx_transact(struct e1000_hw E1000_UNUSEDARG *hw,
588cc64f1eSJack F Vogel 				   u32 E1000_UNUSEDARG *msg,
598cc64f1eSJack F Vogel 				   u16 E1000_UNUSEDARG size,
608cc64f1eSJack F Vogel 				   u16 E1000_UNUSEDARG mbx_id)
61b8270585SJack F Vogel {
62b8270585SJack F Vogel 	DEBUGFUNC("e1000_null_mbx_rw_msg");
63b8270585SJack F Vogel 
64b8270585SJack F Vogel 	return E1000_SUCCESS;
65b8270585SJack F Vogel }
66b8270585SJack F Vogel 
67b8270585SJack F Vogel /**
68b8270585SJack F Vogel  *  e1000_read_mbx - Reads a message from the mailbox
69b8270585SJack F Vogel  *  @hw: pointer to the HW structure
70b8270585SJack F Vogel  *  @msg: The message buffer
71b8270585SJack F Vogel  *  @size: Length of buffer
72b8270585SJack F Vogel  *  @mbx_id: id of mailbox to read
73b8270585SJack F Vogel  *
74363089d8SPedro F. Giffuni  *  returns SUCCESS if it successfully read message from buffer
75b8270585SJack F Vogel  **/
e1000_read_mbx(struct e1000_hw * hw,u32 * msg,u16 size,u16 mbx_id)76b8270585SJack F Vogel s32 e1000_read_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
77b8270585SJack F Vogel {
78b8270585SJack F Vogel 	struct e1000_mbx_info *mbx = &hw->mbx;
79b8270585SJack F Vogel 	s32 ret_val = -E1000_ERR_MBX;
80b8270585SJack F Vogel 
81b8270585SJack F Vogel 	DEBUGFUNC("e1000_read_mbx");
82b8270585SJack F Vogel 
83b8270585SJack F Vogel 	/* limit read to size of mailbox */
84b8270585SJack F Vogel 	if (size > mbx->size)
85b8270585SJack F Vogel 		size = mbx->size;
86b8270585SJack F Vogel 
87b8270585SJack F Vogel 	if (mbx->ops.read)
88b8270585SJack F Vogel 		ret_val = mbx->ops.read(hw, msg, size, mbx_id);
89b8270585SJack F Vogel 
90b8270585SJack F Vogel 	return ret_val;
91b8270585SJack F Vogel }
92b8270585SJack F Vogel 
93b8270585SJack F Vogel /**
94b8270585SJack F Vogel  *  e1000_write_mbx - Write a message to the mailbox
95b8270585SJack F Vogel  *  @hw: pointer to the HW structure
96b8270585SJack F Vogel  *  @msg: The message buffer
97b8270585SJack F Vogel  *  @size: Length of buffer
98b8270585SJack F Vogel  *  @mbx_id: id of mailbox to write
99b8270585SJack F Vogel  *
100b8270585SJack F Vogel  *  returns SUCCESS if it successfully copied message into the buffer
101b8270585SJack F Vogel  **/
e1000_write_mbx(struct e1000_hw * hw,u32 * msg,u16 size,u16 mbx_id)102b8270585SJack F Vogel s32 e1000_write_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
103b8270585SJack F Vogel {
104b8270585SJack F Vogel 	struct e1000_mbx_info *mbx = &hw->mbx;
105b8270585SJack F Vogel 	s32 ret_val = E1000_SUCCESS;
106b8270585SJack F Vogel 
107b8270585SJack F Vogel 	DEBUGFUNC("e1000_write_mbx");
108b8270585SJack F Vogel 
109b8270585SJack F Vogel 	if (size > mbx->size)
110b8270585SJack F Vogel 		ret_val = -E1000_ERR_MBX;
111b8270585SJack F Vogel 
112b8270585SJack F Vogel 	else if (mbx->ops.write)
113b8270585SJack F Vogel 		ret_val = mbx->ops.write(hw, msg, size, mbx_id);
114b8270585SJack F Vogel 
115b8270585SJack F Vogel 	return ret_val;
116b8270585SJack F Vogel }
117b8270585SJack F Vogel 
118b8270585SJack F Vogel /**
119b8270585SJack F Vogel  *  e1000_check_for_msg - checks to see if someone sent us mail
120b8270585SJack F Vogel  *  @hw: pointer to the HW structure
121b8270585SJack F Vogel  *  @mbx_id: id of mailbox to check
122b8270585SJack F Vogel  *
123b8270585SJack F Vogel  *  returns SUCCESS if the Status bit was found or else ERR_MBX
124b8270585SJack F Vogel  **/
e1000_check_for_msg(struct e1000_hw * hw,u16 mbx_id)125b8270585SJack F Vogel s32 e1000_check_for_msg(struct e1000_hw *hw, u16 mbx_id)
126b8270585SJack F Vogel {
127b8270585SJack F Vogel 	struct e1000_mbx_info *mbx = &hw->mbx;
128b8270585SJack F Vogel 	s32 ret_val = -E1000_ERR_MBX;
129b8270585SJack F Vogel 
130b8270585SJack F Vogel 	DEBUGFUNC("e1000_check_for_msg");
131b8270585SJack F Vogel 
132b8270585SJack F Vogel 	if (mbx->ops.check_for_msg)
133b8270585SJack F Vogel 		ret_val = mbx->ops.check_for_msg(hw, mbx_id);
134b8270585SJack F Vogel 
135b8270585SJack F Vogel 	return ret_val;
136b8270585SJack F Vogel }
137b8270585SJack F Vogel 
138b8270585SJack F Vogel /**
139b8270585SJack F Vogel  *  e1000_check_for_ack - checks to see if someone sent us ACK
140b8270585SJack F Vogel  *  @hw: pointer to the HW structure
141b8270585SJack F Vogel  *  @mbx_id: id of mailbox to check
142b8270585SJack F Vogel  *
143b8270585SJack F Vogel  *  returns SUCCESS if the Status bit was found or else ERR_MBX
144b8270585SJack F Vogel  **/
e1000_check_for_ack(struct e1000_hw * hw,u16 mbx_id)145b8270585SJack F Vogel s32 e1000_check_for_ack(struct e1000_hw *hw, u16 mbx_id)
146b8270585SJack F Vogel {
147b8270585SJack F Vogel 	struct e1000_mbx_info *mbx = &hw->mbx;
148b8270585SJack F Vogel 	s32 ret_val = -E1000_ERR_MBX;
149b8270585SJack F Vogel 
150b8270585SJack F Vogel 	DEBUGFUNC("e1000_check_for_ack");
151b8270585SJack F Vogel 
152b8270585SJack F Vogel 	if (mbx->ops.check_for_ack)
153b8270585SJack F Vogel 		ret_val = mbx->ops.check_for_ack(hw, mbx_id);
154b8270585SJack F Vogel 
155b8270585SJack F Vogel 	return ret_val;
156b8270585SJack F Vogel }
157b8270585SJack F Vogel 
158b8270585SJack F Vogel /**
159b8270585SJack F Vogel  *  e1000_check_for_rst - checks to see if other side has reset
160b8270585SJack F Vogel  *  @hw: pointer to the HW structure
161b8270585SJack F Vogel  *  @mbx_id: id of mailbox to check
162b8270585SJack F Vogel  *
163b8270585SJack F Vogel  *  returns SUCCESS if the Status bit was found or else ERR_MBX
164b8270585SJack F Vogel  **/
e1000_check_for_rst(struct e1000_hw * hw,u16 mbx_id)165b8270585SJack F Vogel s32 e1000_check_for_rst(struct e1000_hw *hw, u16 mbx_id)
166b8270585SJack F Vogel {
167b8270585SJack F Vogel 	struct e1000_mbx_info *mbx = &hw->mbx;
168b8270585SJack F Vogel 	s32 ret_val = -E1000_ERR_MBX;
169b8270585SJack F Vogel 
170b8270585SJack F Vogel 	DEBUGFUNC("e1000_check_for_rst");
171b8270585SJack F Vogel 
172b8270585SJack F Vogel 	if (mbx->ops.check_for_rst)
173b8270585SJack F Vogel 		ret_val = mbx->ops.check_for_rst(hw, mbx_id);
174b8270585SJack F Vogel 
175b8270585SJack F Vogel 	return ret_val;
176b8270585SJack F Vogel }
177b8270585SJack F Vogel 
178b8270585SJack F Vogel /**
179b8270585SJack F Vogel  *  e1000_poll_for_msg - Wait for message notification
180b8270585SJack F Vogel  *  @hw: pointer to the HW structure
181b8270585SJack F Vogel  *  @mbx_id: id of mailbox to write
182b8270585SJack F Vogel  *
183b8270585SJack F Vogel  *  returns SUCCESS if it successfully received a message notification
184b8270585SJack F Vogel  **/
e1000_poll_for_msg(struct e1000_hw * hw,u16 mbx_id)185b8270585SJack F Vogel static s32 e1000_poll_for_msg(struct e1000_hw *hw, u16 mbx_id)
186b8270585SJack F Vogel {
187b8270585SJack F Vogel 	struct e1000_mbx_info *mbx = &hw->mbx;
188b8270585SJack F Vogel 	int countdown = mbx->timeout;
189b8270585SJack F Vogel 
190b8270585SJack F Vogel 	DEBUGFUNC("e1000_poll_for_msg");
191b8270585SJack F Vogel 
192b8270585SJack F Vogel 	if (!countdown || !mbx->ops.check_for_msg)
193b8270585SJack F Vogel 		goto out;
194b8270585SJack F Vogel 
195b8270585SJack F Vogel 	while (countdown && mbx->ops.check_for_msg(hw, mbx_id)) {
196b8270585SJack F Vogel 		countdown--;
197b8270585SJack F Vogel 		if (!countdown)
198b8270585SJack F Vogel 			break;
199b8270585SJack F Vogel 		usec_delay(mbx->usec_delay);
200b8270585SJack F Vogel 	}
201b8270585SJack F Vogel 
202b8270585SJack F Vogel 	/* if we failed, all future posted messages fail until reset */
203b8270585SJack F Vogel 	if (!countdown)
204b8270585SJack F Vogel 		mbx->timeout = 0;
205b8270585SJack F Vogel out:
206b8270585SJack F Vogel 	return countdown ? E1000_SUCCESS : -E1000_ERR_MBX;
207b8270585SJack F Vogel }
208b8270585SJack F Vogel 
209b8270585SJack F Vogel /**
210b8270585SJack F Vogel  *  e1000_poll_for_ack - Wait for message acknowledgement
211b8270585SJack F Vogel  *  @hw: pointer to the HW structure
212b8270585SJack F Vogel  *  @mbx_id: id of mailbox to write
213b8270585SJack F Vogel  *
214b8270585SJack F Vogel  *  returns SUCCESS if it successfully received a message acknowledgement
215b8270585SJack F Vogel  **/
e1000_poll_for_ack(struct e1000_hw * hw,u16 mbx_id)216b8270585SJack F Vogel static s32 e1000_poll_for_ack(struct e1000_hw *hw, u16 mbx_id)
217b8270585SJack F Vogel {
218b8270585SJack F Vogel 	struct e1000_mbx_info *mbx = &hw->mbx;
219b8270585SJack F Vogel 	int countdown = mbx->timeout;
220b8270585SJack F Vogel 
221b8270585SJack F Vogel 	DEBUGFUNC("e1000_poll_for_ack");
222b8270585SJack F Vogel 
223b8270585SJack F Vogel 	if (!countdown || !mbx->ops.check_for_ack)
224b8270585SJack F Vogel 		goto out;
225b8270585SJack F Vogel 
226b8270585SJack F Vogel 	while (countdown && mbx->ops.check_for_ack(hw, mbx_id)) {
227b8270585SJack F Vogel 		countdown--;
228b8270585SJack F Vogel 		if (!countdown)
229b8270585SJack F Vogel 			break;
230b8270585SJack F Vogel 		usec_delay(mbx->usec_delay);
231b8270585SJack F Vogel 	}
232b8270585SJack F Vogel 
233b8270585SJack F Vogel 	/* if we failed, all future posted messages fail until reset */
234b8270585SJack F Vogel 	if (!countdown)
235b8270585SJack F Vogel 		mbx->timeout = 0;
236b8270585SJack F Vogel out:
237b8270585SJack F Vogel 	return countdown ? E1000_SUCCESS : -E1000_ERR_MBX;
238b8270585SJack F Vogel }
239b8270585SJack F Vogel 
240b8270585SJack F Vogel /**
241b8270585SJack F Vogel  *  e1000_read_posted_mbx - Wait for message notification and receive message
242b8270585SJack F Vogel  *  @hw: pointer to the HW structure
243b8270585SJack F Vogel  *  @msg: The message buffer
244b8270585SJack F Vogel  *  @size: Length of buffer
245b8270585SJack F Vogel  *  @mbx_id: id of mailbox to write
246b8270585SJack F Vogel  *
247b8270585SJack F Vogel  *  returns SUCCESS if it successfully received a message notification and
248b8270585SJack F Vogel  *  copied it into the receive buffer.
249b8270585SJack F Vogel  **/
e1000_read_posted_mbx(struct e1000_hw * hw,u32 * msg,u16 size,u16 mbx_id)250b8270585SJack F Vogel s32 e1000_read_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
251b8270585SJack F Vogel {
252b8270585SJack F Vogel 	struct e1000_mbx_info *mbx = &hw->mbx;
253b8270585SJack F Vogel 	s32 ret_val = -E1000_ERR_MBX;
254b8270585SJack F Vogel 
255b8270585SJack F Vogel 	DEBUGFUNC("e1000_read_posted_mbx");
256b8270585SJack F Vogel 
257b8270585SJack F Vogel 	if (!mbx->ops.read)
258b8270585SJack F Vogel 		goto out;
259b8270585SJack F Vogel 
260b8270585SJack F Vogel 	ret_val = e1000_poll_for_msg(hw, mbx_id);
261b8270585SJack F Vogel 
262b8270585SJack F Vogel 	/* if ack received read message, otherwise we timed out */
263b8270585SJack F Vogel 	if (!ret_val)
264b8270585SJack F Vogel 		ret_val = mbx->ops.read(hw, msg, size, mbx_id);
265b8270585SJack F Vogel out:
266b8270585SJack F Vogel 	return ret_val;
267b8270585SJack F Vogel }
268b8270585SJack F Vogel 
269b8270585SJack F Vogel /**
270b8270585SJack F Vogel  *  e1000_write_posted_mbx - Write a message to the mailbox, wait for ack
271b8270585SJack F Vogel  *  @hw: pointer to the HW structure
272b8270585SJack F Vogel  *  @msg: The message buffer
273b8270585SJack F Vogel  *  @size: Length of buffer
274b8270585SJack F Vogel  *  @mbx_id: id of mailbox to write
275b8270585SJack F Vogel  *
276b8270585SJack F Vogel  *  returns SUCCESS if it successfully copied message into the buffer and
277b8270585SJack F Vogel  *  received an ack to that message within delay * timeout period
278b8270585SJack F Vogel  **/
e1000_write_posted_mbx(struct e1000_hw * hw,u32 * msg,u16 size,u16 mbx_id)279b8270585SJack F Vogel s32 e1000_write_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
280b8270585SJack F Vogel {
281b8270585SJack F Vogel 	struct e1000_mbx_info *mbx = &hw->mbx;
282b8270585SJack F Vogel 	s32 ret_val = -E1000_ERR_MBX;
283b8270585SJack F Vogel 
284b8270585SJack F Vogel 	DEBUGFUNC("e1000_write_posted_mbx");
285b8270585SJack F Vogel 
286b8270585SJack F Vogel 	/* exit if either we can't write or there isn't a defined timeout */
287b8270585SJack F Vogel 	if (!mbx->ops.write || !mbx->timeout)
288b8270585SJack F Vogel 		goto out;
289b8270585SJack F Vogel 
290b8270585SJack F Vogel 	/* send msg */
291b8270585SJack F Vogel 	ret_val = mbx->ops.write(hw, msg, size, mbx_id);
292b8270585SJack F Vogel 
293b8270585SJack F Vogel 	/* if msg sent wait until we receive an ack */
294b8270585SJack F Vogel 	if (!ret_val)
295b8270585SJack F Vogel 		ret_val = e1000_poll_for_ack(hw, mbx_id);
296b8270585SJack F Vogel out:
297b8270585SJack F Vogel 	return ret_val;
298b8270585SJack F Vogel }
299b8270585SJack F Vogel 
300b8270585SJack F Vogel /**
301b8270585SJack F Vogel  *  e1000_init_mbx_ops_generic - Initialize mbx function pointers
302b8270585SJack F Vogel  *  @hw: pointer to the HW structure
303b8270585SJack F Vogel  *
304b8270585SJack F Vogel  *  Sets the function pointers to no-op functions
305b8270585SJack F Vogel  **/
e1000_init_mbx_ops_generic(struct e1000_hw * hw)306b8270585SJack F Vogel void e1000_init_mbx_ops_generic(struct e1000_hw *hw)
307b8270585SJack F Vogel {
308b8270585SJack F Vogel 	struct e1000_mbx_info *mbx = &hw->mbx;
309b8270585SJack F Vogel 	mbx->ops.init_params = e1000_null_ops_generic;
310b8270585SJack F Vogel 	mbx->ops.read = e1000_null_mbx_transact;
311b8270585SJack F Vogel 	mbx->ops.write = e1000_null_mbx_transact;
312b8270585SJack F Vogel 	mbx->ops.check_for_msg = e1000_null_mbx_check_for_flag;
313b8270585SJack F Vogel 	mbx->ops.check_for_ack = e1000_null_mbx_check_for_flag;
314b8270585SJack F Vogel 	mbx->ops.check_for_rst = e1000_null_mbx_check_for_flag;
315b8270585SJack F Vogel 	mbx->ops.read_posted = e1000_read_posted_mbx;
316b8270585SJack F Vogel 	mbx->ops.write_posted = e1000_write_posted_mbx;
317b8270585SJack F Vogel }
318b8270585SJack F Vogel 
319b8270585SJack F Vogel /**
320b8270585SJack F Vogel  *  e1000_read_v2p_mailbox - read v2p mailbox
321b8270585SJack F Vogel  *  @hw: pointer to the HW structure
322b8270585SJack F Vogel  *
323b8270585SJack F Vogel  *  This function is used to read the v2p mailbox without losing the read to
324b8270585SJack F Vogel  *  clear status bits.
325b8270585SJack F Vogel  **/
e1000_read_v2p_mailbox(struct e1000_hw * hw)326b8270585SJack F Vogel static u32 e1000_read_v2p_mailbox(struct e1000_hw *hw)
327b8270585SJack F Vogel {
328b8270585SJack F Vogel 	u32 v2p_mailbox = E1000_READ_REG(hw, E1000_V2PMAILBOX(0));
329b8270585SJack F Vogel 
330b8270585SJack F Vogel 	v2p_mailbox |= hw->dev_spec.vf.v2p_mailbox;
331b8270585SJack F Vogel 	hw->dev_spec.vf.v2p_mailbox |= v2p_mailbox & E1000_V2PMAILBOX_R2C_BITS;
332b8270585SJack F Vogel 
333b8270585SJack F Vogel 	return v2p_mailbox;
334b8270585SJack F Vogel }
335b8270585SJack F Vogel 
336b8270585SJack F Vogel /**
337b8270585SJack F Vogel  *  e1000_check_for_bit_vf - Determine if a status bit was set
338b8270585SJack F Vogel  *  @hw: pointer to the HW structure
339b8270585SJack F Vogel  *  @mask: bitmask for bits to be tested and cleared
340b8270585SJack F Vogel  *
341b8270585SJack F Vogel  *  This function is used to check for the read to clear bits within
342b8270585SJack F Vogel  *  the V2P mailbox.
343b8270585SJack F Vogel  **/
e1000_check_for_bit_vf(struct e1000_hw * hw,u32 mask)344b8270585SJack F Vogel static s32 e1000_check_for_bit_vf(struct e1000_hw *hw, u32 mask)
345b8270585SJack F Vogel {
346b8270585SJack F Vogel 	u32 v2p_mailbox = e1000_read_v2p_mailbox(hw);
347b8270585SJack F Vogel 	s32 ret_val = -E1000_ERR_MBX;
348b8270585SJack F Vogel 
349b8270585SJack F Vogel 	if (v2p_mailbox & mask)
350b8270585SJack F Vogel 		ret_val = E1000_SUCCESS;
351b8270585SJack F Vogel 
352b8270585SJack F Vogel 	hw->dev_spec.vf.v2p_mailbox &= ~mask;
353b8270585SJack F Vogel 
354b8270585SJack F Vogel 	return ret_val;
355b8270585SJack F Vogel }
356b8270585SJack F Vogel 
357b8270585SJack F Vogel /**
358b8270585SJack F Vogel  *  e1000_check_for_msg_vf - checks to see if the PF has sent mail
359b8270585SJack F Vogel  *  @hw: pointer to the HW structure
360b8270585SJack F Vogel  *  @mbx_id: id of mailbox to check
361b8270585SJack F Vogel  *
362b8270585SJack F Vogel  *  returns SUCCESS if the PF has set the Status bit or else ERR_MBX
363b8270585SJack F Vogel  **/
e1000_check_for_msg_vf(struct e1000_hw * hw,u16 E1000_UNUSEDARG mbx_id)3648cc64f1eSJack F Vogel static s32 e1000_check_for_msg_vf(struct e1000_hw *hw,
3658cc64f1eSJack F Vogel 				  u16 E1000_UNUSEDARG mbx_id)
366b8270585SJack F Vogel {
367b8270585SJack F Vogel 	s32 ret_val = -E1000_ERR_MBX;
368b8270585SJack F Vogel 
369b8270585SJack F Vogel 	DEBUGFUNC("e1000_check_for_msg_vf");
370b8270585SJack F Vogel 
371b8270585SJack F Vogel 	if (!e1000_check_for_bit_vf(hw, E1000_V2PMAILBOX_PFSTS)) {
372b8270585SJack F Vogel 		ret_val = E1000_SUCCESS;
373b8270585SJack F Vogel 		hw->mbx.stats.reqs++;
374b8270585SJack F Vogel 	}
375b8270585SJack F Vogel 
376b8270585SJack F Vogel 	return ret_val;
377b8270585SJack F Vogel }
378b8270585SJack F Vogel 
379b8270585SJack F Vogel /**
380b8270585SJack F Vogel  *  e1000_check_for_ack_vf - checks to see if the PF has ACK'd
381b8270585SJack F Vogel  *  @hw: pointer to the HW structure
382b8270585SJack F Vogel  *  @mbx_id: id of mailbox to check
383b8270585SJack F Vogel  *
384b8270585SJack F Vogel  *  returns SUCCESS if the PF has set the ACK bit or else ERR_MBX
385b8270585SJack F Vogel  **/
e1000_check_for_ack_vf(struct e1000_hw * hw,u16 E1000_UNUSEDARG mbx_id)3868cc64f1eSJack F Vogel static s32 e1000_check_for_ack_vf(struct e1000_hw *hw,
3878cc64f1eSJack F Vogel 				  u16 E1000_UNUSEDARG mbx_id)
388b8270585SJack F Vogel {
389b8270585SJack F Vogel 	s32 ret_val = -E1000_ERR_MBX;
390b8270585SJack F Vogel 
391b8270585SJack F Vogel 	DEBUGFUNC("e1000_check_for_ack_vf");
392b8270585SJack F Vogel 
393b8270585SJack F Vogel 	if (!e1000_check_for_bit_vf(hw, E1000_V2PMAILBOX_PFACK)) {
394b8270585SJack F Vogel 		ret_val = E1000_SUCCESS;
395b8270585SJack F Vogel 		hw->mbx.stats.acks++;
396b8270585SJack F Vogel 	}
397b8270585SJack F Vogel 
398b8270585SJack F Vogel 	return ret_val;
399b8270585SJack F Vogel }
400b8270585SJack F Vogel 
401b8270585SJack F Vogel /**
402b8270585SJack F Vogel  *  e1000_check_for_rst_vf - checks to see if the PF has reset
403b8270585SJack F Vogel  *  @hw: pointer to the HW structure
404b8270585SJack F Vogel  *  @mbx_id: id of mailbox to check
405b8270585SJack F Vogel  *
406*1bbdc25fSKevin Bowling  *  returns true if the PF has set the reset done bit or else false
407b8270585SJack F Vogel  **/
e1000_check_for_rst_vf(struct e1000_hw * hw,u16 E1000_UNUSEDARG mbx_id)4088cc64f1eSJack F Vogel static s32 e1000_check_for_rst_vf(struct e1000_hw *hw,
4098cc64f1eSJack F Vogel 				  u16 E1000_UNUSEDARG mbx_id)
410b8270585SJack F Vogel {
411b8270585SJack F Vogel 	s32 ret_val = -E1000_ERR_MBX;
412b8270585SJack F Vogel 
413b8270585SJack F Vogel 	DEBUGFUNC("e1000_check_for_rst_vf");
414b8270585SJack F Vogel 
415b8270585SJack F Vogel 	if (!e1000_check_for_bit_vf(hw, (E1000_V2PMAILBOX_RSTD |
416b8270585SJack F Vogel 					 E1000_V2PMAILBOX_RSTI))) {
417b8270585SJack F Vogel 		ret_val = E1000_SUCCESS;
418b8270585SJack F Vogel 		hw->mbx.stats.rsts++;
419b8270585SJack F Vogel 	}
420b8270585SJack F Vogel 
421b8270585SJack F Vogel 	return ret_val;
422b8270585SJack F Vogel }
423b8270585SJack F Vogel 
424b8270585SJack F Vogel /**
425b8270585SJack F Vogel  *  e1000_obtain_mbx_lock_vf - obtain mailbox lock
426b8270585SJack F Vogel  *  @hw: pointer to the HW structure
427b8270585SJack F Vogel  *
428b8270585SJack F Vogel  *  return SUCCESS if we obtained the mailbox lock
429b8270585SJack F Vogel  **/
e1000_obtain_mbx_lock_vf(struct e1000_hw * hw)430b8270585SJack F Vogel static s32 e1000_obtain_mbx_lock_vf(struct e1000_hw *hw)
431b8270585SJack F Vogel {
432b8270585SJack F Vogel 	s32 ret_val = -E1000_ERR_MBX;
433c80429ceSEric Joyner 	int count = 10;
434b8270585SJack F Vogel 
435b8270585SJack F Vogel 	DEBUGFUNC("e1000_obtain_mbx_lock_vf");
436b8270585SJack F Vogel 
437c80429ceSEric Joyner 	do {
438b8270585SJack F Vogel 		/* Take ownership of the buffer */
439b8270585SJack F Vogel 		E1000_WRITE_REG(hw, E1000_V2PMAILBOX(0), E1000_V2PMAILBOX_VFU);
440b8270585SJack F Vogel 
441b8270585SJack F Vogel 		/* reserve mailbox for vf use */
442c80429ceSEric Joyner 		if (e1000_read_v2p_mailbox(hw) & E1000_V2PMAILBOX_VFU) {
443b8270585SJack F Vogel 			ret_val = E1000_SUCCESS;
444c80429ceSEric Joyner 			break;
445c80429ceSEric Joyner 		}
446c80429ceSEric Joyner 		usec_delay(1000);
447c80429ceSEric Joyner 	} while (count-- > 0);
448b8270585SJack F Vogel 
449b8270585SJack F Vogel 	return ret_val;
450b8270585SJack F Vogel }
451b8270585SJack F Vogel 
452b8270585SJack F Vogel /**
453b8270585SJack F Vogel  *  e1000_write_mbx_vf - Write a message to the mailbox
454b8270585SJack F Vogel  *  @hw: pointer to the HW structure
455b8270585SJack F Vogel  *  @msg: The message buffer
456b8270585SJack F Vogel  *  @size: Length of buffer
457b8270585SJack F Vogel  *  @mbx_id: id of mailbox to write
458b8270585SJack F Vogel  *
459b8270585SJack F Vogel  *  returns SUCCESS if it successfully copied message into the buffer
460b8270585SJack F Vogel  **/
e1000_write_mbx_vf(struct e1000_hw * hw,u32 * msg,u16 size,u16 E1000_UNUSEDARG mbx_id)461b8270585SJack F Vogel static s32 e1000_write_mbx_vf(struct e1000_hw *hw, u32 *msg, u16 size,
4628cc64f1eSJack F Vogel 			      u16 E1000_UNUSEDARG mbx_id)
463b8270585SJack F Vogel {
464b8270585SJack F Vogel 	s32 ret_val;
465b8270585SJack F Vogel 	u16 i;
466b8270585SJack F Vogel 
467b8270585SJack F Vogel 
468b8270585SJack F Vogel 	DEBUGFUNC("e1000_write_mbx_vf");
469b8270585SJack F Vogel 
470b8270585SJack F Vogel 	/* lock the mailbox to prevent pf/vf race condition */
471b8270585SJack F Vogel 	ret_val = e1000_obtain_mbx_lock_vf(hw);
472b8270585SJack F Vogel 	if (ret_val)
473b8270585SJack F Vogel 		goto out_no_write;
474b8270585SJack F Vogel 
475b8270585SJack F Vogel 	/* flush msg and acks as we are overwriting the message buffer */
476b8270585SJack F Vogel 	e1000_check_for_msg_vf(hw, 0);
477b8270585SJack F Vogel 	e1000_check_for_ack_vf(hw, 0);
478b8270585SJack F Vogel 
479b8270585SJack F Vogel 	/* copy the caller specified message to the mailbox memory buffer */
480b8270585SJack F Vogel 	for (i = 0; i < size; i++)
481b8270585SJack F Vogel 		E1000_WRITE_REG_ARRAY(hw, E1000_VMBMEM(0), i, msg[i]);
482b8270585SJack F Vogel 
483b8270585SJack F Vogel 	/* update stats */
484b8270585SJack F Vogel 	hw->mbx.stats.msgs_tx++;
485b8270585SJack F Vogel 
486b8270585SJack F Vogel 	/* Drop VFU and interrupt the PF to tell it a message has been sent */
487b8270585SJack F Vogel 	E1000_WRITE_REG(hw, E1000_V2PMAILBOX(0), E1000_V2PMAILBOX_REQ);
488b8270585SJack F Vogel 
489b8270585SJack F Vogel out_no_write:
490b8270585SJack F Vogel 	return ret_val;
491b8270585SJack F Vogel }
492b8270585SJack F Vogel 
493b8270585SJack F Vogel /**
494b8270585SJack F Vogel  *  e1000_read_mbx_vf - Reads a message from the inbox intended for vf
495b8270585SJack F Vogel  *  @hw: pointer to the HW structure
496b8270585SJack F Vogel  *  @msg: The message buffer
497b8270585SJack F Vogel  *  @size: Length of buffer
498b8270585SJack F Vogel  *  @mbx_id: id of mailbox to read
499b8270585SJack F Vogel  *
500363089d8SPedro F. Giffuni  *  returns SUCCESS if it successfully read message from buffer
501b8270585SJack F Vogel  **/
e1000_read_mbx_vf(struct e1000_hw * hw,u32 * msg,u16 size,u16 E1000_UNUSEDARG mbx_id)502b8270585SJack F Vogel static s32 e1000_read_mbx_vf(struct e1000_hw *hw, u32 *msg, u16 size,
5038cc64f1eSJack F Vogel 			     u16 E1000_UNUSEDARG mbx_id)
504b8270585SJack F Vogel {
505b8270585SJack F Vogel 	s32 ret_val = E1000_SUCCESS;
506b8270585SJack F Vogel 	u16 i;
507b8270585SJack F Vogel 
508b8270585SJack F Vogel 	DEBUGFUNC("e1000_read_mbx_vf");
509b8270585SJack F Vogel 
510b8270585SJack F Vogel 	/* lock the mailbox to prevent pf/vf race condition */
511b8270585SJack F Vogel 	ret_val = e1000_obtain_mbx_lock_vf(hw);
512b8270585SJack F Vogel 	if (ret_val)
513b8270585SJack F Vogel 		goto out_no_read;
514b8270585SJack F Vogel 
515b8270585SJack F Vogel 	/* copy the message from the mailbox memory buffer */
516b8270585SJack F Vogel 	for (i = 0; i < size; i++)
517b8270585SJack F Vogel 		msg[i] = E1000_READ_REG_ARRAY(hw, E1000_VMBMEM(0), i);
518b8270585SJack F Vogel 
519b8270585SJack F Vogel 	/* Acknowledge receipt and release mailbox, then we're done */
520b8270585SJack F Vogel 	E1000_WRITE_REG(hw, E1000_V2PMAILBOX(0), E1000_V2PMAILBOX_ACK);
521b8270585SJack F Vogel 
522b8270585SJack F Vogel 	/* update stats */
523b8270585SJack F Vogel 	hw->mbx.stats.msgs_rx++;
524b8270585SJack F Vogel 
525b8270585SJack F Vogel out_no_read:
526b8270585SJack F Vogel 	return ret_val;
527b8270585SJack F Vogel }
528b8270585SJack F Vogel 
529b8270585SJack F Vogel /**
530b8270585SJack F Vogel  *  e1000_init_mbx_params_vf - set initial values for vf mailbox
531b8270585SJack F Vogel  *  @hw: pointer to the HW structure
532b8270585SJack F Vogel  *
533b8270585SJack F Vogel  *  Initializes the hw->mbx struct to correct values for vf mailbox
534b8270585SJack F Vogel  */
e1000_init_mbx_params_vf(struct e1000_hw * hw)535b8270585SJack F Vogel s32 e1000_init_mbx_params_vf(struct e1000_hw *hw)
536b8270585SJack F Vogel {
537b8270585SJack F Vogel 	struct e1000_mbx_info *mbx = &hw->mbx;
538b8270585SJack F Vogel 
539b8270585SJack F Vogel 	/* start mailbox as timed out and let the reset_hw call set the timeout
540b8270585SJack F Vogel 	 * value to begin communications */
541b8270585SJack F Vogel 	mbx->timeout = 0;
542b8270585SJack F Vogel 	mbx->usec_delay = E1000_VF_MBX_INIT_DELAY;
543b8270585SJack F Vogel 
544b8270585SJack F Vogel 	mbx->size = E1000_VFMAILBOX_SIZE;
545b8270585SJack F Vogel 
546b8270585SJack F Vogel 	mbx->ops.read = e1000_read_mbx_vf;
547b8270585SJack F Vogel 	mbx->ops.write = e1000_write_mbx_vf;
548b8270585SJack F Vogel 	mbx->ops.read_posted = e1000_read_posted_mbx;
549b8270585SJack F Vogel 	mbx->ops.write_posted = e1000_write_posted_mbx;
550b8270585SJack F Vogel 	mbx->ops.check_for_msg = e1000_check_for_msg_vf;
551b8270585SJack F Vogel 	mbx->ops.check_for_ack = e1000_check_for_ack_vf;
552b8270585SJack F Vogel 	mbx->ops.check_for_rst = e1000_check_for_rst_vf;
553b8270585SJack F Vogel 
554b8270585SJack F Vogel 	mbx->stats.msgs_tx = 0;
555b8270585SJack F Vogel 	mbx->stats.msgs_rx = 0;
556b8270585SJack F Vogel 	mbx->stats.reqs = 0;
557b8270585SJack F Vogel 	mbx->stats.acks = 0;
558b8270585SJack F Vogel 	mbx->stats.rsts = 0;
559b8270585SJack F Vogel 
560b8270585SJack F Vogel 	return E1000_SUCCESS;
561b8270585SJack F Vogel }
562b8270585SJack F Vogel 
e1000_check_for_bit_pf(struct e1000_hw * hw,u32 mask)563b8270585SJack F Vogel static s32 e1000_check_for_bit_pf(struct e1000_hw *hw, u32 mask)
564b8270585SJack F Vogel {
565b8270585SJack F Vogel 	u32 mbvficr = E1000_READ_REG(hw, E1000_MBVFICR);
566b8270585SJack F Vogel 	s32 ret_val = -E1000_ERR_MBX;
567b8270585SJack F Vogel 
568b8270585SJack F Vogel 	if (mbvficr & mask) {
569b8270585SJack F Vogel 		ret_val = E1000_SUCCESS;
570b8270585SJack F Vogel 		E1000_WRITE_REG(hw, E1000_MBVFICR, mask);
571b8270585SJack F Vogel 	}
572b8270585SJack F Vogel 
573b8270585SJack F Vogel 	return ret_val;
574b8270585SJack F Vogel }
575b8270585SJack F Vogel 
576b8270585SJack F Vogel /**
577b8270585SJack F Vogel  *  e1000_check_for_msg_pf - checks to see if the VF has sent mail
578b8270585SJack F Vogel  *  @hw: pointer to the HW structure
579b8270585SJack F Vogel  *  @vf_number: the VF index
580b8270585SJack F Vogel  *
581b8270585SJack F Vogel  *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
582b8270585SJack F Vogel  **/
e1000_check_for_msg_pf(struct e1000_hw * hw,u16 vf_number)583b8270585SJack F Vogel static s32 e1000_check_for_msg_pf(struct e1000_hw *hw, u16 vf_number)
584b8270585SJack F Vogel {
585b8270585SJack F Vogel 	s32 ret_val = -E1000_ERR_MBX;
586b8270585SJack F Vogel 
587b8270585SJack F Vogel 	DEBUGFUNC("e1000_check_for_msg_pf");
588b8270585SJack F Vogel 
589b8270585SJack F Vogel 	if (!e1000_check_for_bit_pf(hw, E1000_MBVFICR_VFREQ_VF1 << vf_number)) {
590b8270585SJack F Vogel 		ret_val = E1000_SUCCESS;
591b8270585SJack F Vogel 		hw->mbx.stats.reqs++;
592b8270585SJack F Vogel 	}
593b8270585SJack F Vogel 
594b8270585SJack F Vogel 	return ret_val;
595b8270585SJack F Vogel }
596b8270585SJack F Vogel 
597b8270585SJack F Vogel /**
598b8270585SJack F Vogel  *  e1000_check_for_ack_pf - checks to see if the VF has ACKed
599b8270585SJack F Vogel  *  @hw: pointer to the HW structure
600b8270585SJack F Vogel  *  @vf_number: the VF index
601b8270585SJack F Vogel  *
602b8270585SJack F Vogel  *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
603b8270585SJack F Vogel  **/
e1000_check_for_ack_pf(struct e1000_hw * hw,u16 vf_number)604b8270585SJack F Vogel static s32 e1000_check_for_ack_pf(struct e1000_hw *hw, u16 vf_number)
605b8270585SJack F Vogel {
606b8270585SJack F Vogel 	s32 ret_val = -E1000_ERR_MBX;
607b8270585SJack F Vogel 
608b8270585SJack F Vogel 	DEBUGFUNC("e1000_check_for_ack_pf");
609b8270585SJack F Vogel 
610b8270585SJack F Vogel 	if (!e1000_check_for_bit_pf(hw, E1000_MBVFICR_VFACK_VF1 << vf_number)) {
611b8270585SJack F Vogel 		ret_val = E1000_SUCCESS;
612b8270585SJack F Vogel 		hw->mbx.stats.acks++;
613b8270585SJack F Vogel 	}
614b8270585SJack F Vogel 
615b8270585SJack F Vogel 	return ret_val;
616b8270585SJack F Vogel }
617b8270585SJack F Vogel 
618b8270585SJack F Vogel /**
619b8270585SJack F Vogel  *  e1000_check_for_rst_pf - checks to see if the VF has reset
620b8270585SJack F Vogel  *  @hw: pointer to the HW structure
621b8270585SJack F Vogel  *  @vf_number: the VF index
622b8270585SJack F Vogel  *
623b8270585SJack F Vogel  *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
624b8270585SJack F Vogel  **/
e1000_check_for_rst_pf(struct e1000_hw * hw,u16 vf_number)625b8270585SJack F Vogel static s32 e1000_check_for_rst_pf(struct e1000_hw *hw, u16 vf_number)
626b8270585SJack F Vogel {
627b8270585SJack F Vogel 	u32 vflre = E1000_READ_REG(hw, E1000_VFLRE);
628b8270585SJack F Vogel 	s32 ret_val = -E1000_ERR_MBX;
629b8270585SJack F Vogel 
630b8270585SJack F Vogel 	DEBUGFUNC("e1000_check_for_rst_pf");
631b8270585SJack F Vogel 
632b8270585SJack F Vogel 	if (vflre & (1 << vf_number)) {
633b8270585SJack F Vogel 		ret_val = E1000_SUCCESS;
634b8270585SJack F Vogel 		E1000_WRITE_REG(hw, E1000_VFLRE, (1 << vf_number));
635b8270585SJack F Vogel 		hw->mbx.stats.rsts++;
636b8270585SJack F Vogel 	}
637b8270585SJack F Vogel 
638b8270585SJack F Vogel 	return ret_val;
639b8270585SJack F Vogel }
640b8270585SJack F Vogel 
641b8270585SJack F Vogel /**
642b8270585SJack F Vogel  *  e1000_obtain_mbx_lock_pf - obtain mailbox lock
643b8270585SJack F Vogel  *  @hw: pointer to the HW structure
644b8270585SJack F Vogel  *  @vf_number: the VF index
645b8270585SJack F Vogel  *
646b8270585SJack F Vogel  *  return SUCCESS if we obtained the mailbox lock
647b8270585SJack F Vogel  **/
e1000_obtain_mbx_lock_pf(struct e1000_hw * hw,u16 vf_number)648b8270585SJack F Vogel static s32 e1000_obtain_mbx_lock_pf(struct e1000_hw *hw, u16 vf_number)
649b8270585SJack F Vogel {
650b8270585SJack F Vogel 	s32 ret_val = -E1000_ERR_MBX;
651b8270585SJack F Vogel 	u32 p2v_mailbox;
652c80429ceSEric Joyner 	int count = 10;
653b8270585SJack F Vogel 
654b8270585SJack F Vogel 	DEBUGFUNC("e1000_obtain_mbx_lock_pf");
655b8270585SJack F Vogel 
656c80429ceSEric Joyner 	do {
657b8270585SJack F Vogel 		/* Take ownership of the buffer */
658c80429ceSEric Joyner 		E1000_WRITE_REG(hw, E1000_P2VMAILBOX(vf_number),
659c80429ceSEric Joyner 				E1000_P2VMAILBOX_PFU);
660b8270585SJack F Vogel 
661c80429ceSEric Joyner 		/* reserve mailbox for pf use */
662b8270585SJack F Vogel 		p2v_mailbox = E1000_READ_REG(hw, E1000_P2VMAILBOX(vf_number));
663c80429ceSEric Joyner 		if (p2v_mailbox & E1000_P2VMAILBOX_PFU) {
664b8270585SJack F Vogel 			ret_val = E1000_SUCCESS;
665c80429ceSEric Joyner 			break;
666c80429ceSEric Joyner 		}
667c80429ceSEric Joyner 		usec_delay(1000);
668c80429ceSEric Joyner 	} while (count-- > 0);
669b8270585SJack F Vogel 
670b8270585SJack F Vogel 	return ret_val;
671c80429ceSEric Joyner 
672b8270585SJack F Vogel }
673b8270585SJack F Vogel 
674b8270585SJack F Vogel /**
675b8270585SJack F Vogel  *  e1000_write_mbx_pf - Places a message in the mailbox
676b8270585SJack F Vogel  *  @hw: pointer to the HW structure
677b8270585SJack F Vogel  *  @msg: The message buffer
678b8270585SJack F Vogel  *  @size: Length of buffer
679b8270585SJack F Vogel  *  @vf_number: the VF index
680b8270585SJack F Vogel  *
681b8270585SJack F Vogel  *  returns SUCCESS if it successfully copied message into the buffer
682b8270585SJack F Vogel  **/
e1000_write_mbx_pf(struct e1000_hw * hw,u32 * msg,u16 size,u16 vf_number)683b8270585SJack F Vogel static s32 e1000_write_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size,
684b8270585SJack F Vogel 			      u16 vf_number)
685b8270585SJack F Vogel {
686b8270585SJack F Vogel 	s32 ret_val;
687b8270585SJack F Vogel 	u16 i;
688b8270585SJack F Vogel 
689b8270585SJack F Vogel 	DEBUGFUNC("e1000_write_mbx_pf");
690b8270585SJack F Vogel 
691b8270585SJack F Vogel 	/* lock the mailbox to prevent pf/vf race condition */
692b8270585SJack F Vogel 	ret_val = e1000_obtain_mbx_lock_pf(hw, vf_number);
693b8270585SJack F Vogel 	if (ret_val)
694b8270585SJack F Vogel 		goto out_no_write;
695b8270585SJack F Vogel 
696b8270585SJack F Vogel 	/* flush msg and acks as we are overwriting the message buffer */
697b8270585SJack F Vogel 	e1000_check_for_msg_pf(hw, vf_number);
698b8270585SJack F Vogel 	e1000_check_for_ack_pf(hw, vf_number);
699b8270585SJack F Vogel 
700b8270585SJack F Vogel 	/* copy the caller specified message to the mailbox memory buffer */
701b8270585SJack F Vogel 	for (i = 0; i < size; i++)
702b8270585SJack F Vogel 		E1000_WRITE_REG_ARRAY(hw, E1000_VMBMEM(vf_number), i, msg[i]);
703b8270585SJack F Vogel 
704b8270585SJack F Vogel 	/* Interrupt VF to tell it a message has been sent and release buffer*/
705b8270585SJack F Vogel 	E1000_WRITE_REG(hw, E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_STS);
706b8270585SJack F Vogel 
707b8270585SJack F Vogel 	/* update stats */
708b8270585SJack F Vogel 	hw->mbx.stats.msgs_tx++;
709b8270585SJack F Vogel 
710b8270585SJack F Vogel out_no_write:
711b8270585SJack F Vogel 	return ret_val;
712b8270585SJack F Vogel 
713b8270585SJack F Vogel }
714b8270585SJack F Vogel 
715b8270585SJack F Vogel /**
716b8270585SJack F Vogel  *  e1000_read_mbx_pf - Read a message from the mailbox
717b8270585SJack F Vogel  *  @hw: pointer to the HW structure
718b8270585SJack F Vogel  *  @msg: The message buffer
719b8270585SJack F Vogel  *  @size: Length of buffer
720b8270585SJack F Vogel  *  @vf_number: the VF index
721b8270585SJack F Vogel  *
722b8270585SJack F Vogel  *  This function copies a message from the mailbox buffer to the caller's
723b8270585SJack F Vogel  *  memory buffer.  The presumption is that the caller knows that there was
724b8270585SJack F Vogel  *  a message due to a VF request so no polling for message is needed.
725b8270585SJack F Vogel  **/
e1000_read_mbx_pf(struct e1000_hw * hw,u32 * msg,u16 size,u16 vf_number)726b8270585SJack F Vogel static s32 e1000_read_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size,
727b8270585SJack F Vogel 			     u16 vf_number)
728b8270585SJack F Vogel {
729b8270585SJack F Vogel 	s32 ret_val;
730b8270585SJack F Vogel 	u16 i;
731b8270585SJack F Vogel 
732b8270585SJack F Vogel 	DEBUGFUNC("e1000_read_mbx_pf");
733b8270585SJack F Vogel 
734b8270585SJack F Vogel 	/* lock the mailbox to prevent pf/vf race condition */
735b8270585SJack F Vogel 	ret_val = e1000_obtain_mbx_lock_pf(hw, vf_number);
736b8270585SJack F Vogel 	if (ret_val)
737b8270585SJack F Vogel 		goto out_no_read;
738b8270585SJack F Vogel 
739b8270585SJack F Vogel 	/* copy the message to the mailbox memory buffer */
740b8270585SJack F Vogel 	for (i = 0; i < size; i++)
741b8270585SJack F Vogel 		msg[i] = E1000_READ_REG_ARRAY(hw, E1000_VMBMEM(vf_number), i);
742b8270585SJack F Vogel 
743b8270585SJack F Vogel 	/* Acknowledge the message and release buffer */
744b8270585SJack F Vogel 	E1000_WRITE_REG(hw, E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_ACK);
745b8270585SJack F Vogel 
746b8270585SJack F Vogel 	/* update stats */
747b8270585SJack F Vogel 	hw->mbx.stats.msgs_rx++;
748b8270585SJack F Vogel 
749b8270585SJack F Vogel out_no_read:
750b8270585SJack F Vogel 	return ret_val;
751b8270585SJack F Vogel }
752b8270585SJack F Vogel 
753b8270585SJack F Vogel /**
754b8270585SJack F Vogel  *  e1000_init_mbx_params_pf - set initial values for pf mailbox
755b8270585SJack F Vogel  *  @hw: pointer to the HW structure
756b8270585SJack F Vogel  *
757b8270585SJack F Vogel  *  Initializes the hw->mbx struct to correct values for pf mailbox
758b8270585SJack F Vogel  */
e1000_init_mbx_params_pf(struct e1000_hw * hw)759b8270585SJack F Vogel s32 e1000_init_mbx_params_pf(struct e1000_hw *hw)
760b8270585SJack F Vogel {
761b8270585SJack F Vogel 	struct e1000_mbx_info *mbx = &hw->mbx;
762b8270585SJack F Vogel 
763f0ecc46dSJack F Vogel 	switch (hw->mac.type) {
764f0ecc46dSJack F Vogel 	case e1000_82576:
765f0ecc46dSJack F Vogel 	case e1000_i350:
7668cc64f1eSJack F Vogel 	case e1000_i354:
767b8270585SJack F Vogel 		mbx->timeout = 0;
768b8270585SJack F Vogel 		mbx->usec_delay = 0;
769b8270585SJack F Vogel 
770b8270585SJack F Vogel 		mbx->size = E1000_VFMAILBOX_SIZE;
771b8270585SJack F Vogel 
772b8270585SJack F Vogel 		mbx->ops.read = e1000_read_mbx_pf;
773b8270585SJack F Vogel 		mbx->ops.write = e1000_write_mbx_pf;
774b8270585SJack F Vogel 		mbx->ops.read_posted = e1000_read_posted_mbx;
775b8270585SJack F Vogel 		mbx->ops.write_posted = e1000_write_posted_mbx;
776b8270585SJack F Vogel 		mbx->ops.check_for_msg = e1000_check_for_msg_pf;
777b8270585SJack F Vogel 		mbx->ops.check_for_ack = e1000_check_for_ack_pf;
778b8270585SJack F Vogel 		mbx->ops.check_for_rst = e1000_check_for_rst_pf;
779b8270585SJack F Vogel 
780b8270585SJack F Vogel 		mbx->stats.msgs_tx = 0;
781b8270585SJack F Vogel 		mbx->stats.msgs_rx = 0;
782b8270585SJack F Vogel 		mbx->stats.reqs = 0;
783b8270585SJack F Vogel 		mbx->stats.acks = 0;
784b8270585SJack F Vogel 		mbx->stats.rsts = 0;
785a5b0fd9cSToomas Soome 		/* FALLTHROUGH */
786f0ecc46dSJack F Vogel 	default:
787b8270585SJack F Vogel 		return E1000_SUCCESS;
788b8270585SJack F Vogel 	}
789f0ecc46dSJack F Vogel }
790b8270585SJack F Vogel 
791