1cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose/*******************************************************************************
2cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
3cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose  Intel 82599 Virtual Function driver
45c47a2b6211316ee9cd8740db453af7c5c01d0d6Greg Rose  Copyright(c) 1999 - 2012 Intel Corporation.
5cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
6cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose  This program is free software; you can redistribute it and/or modify it
7cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose  under the terms and conditions of the GNU General Public License,
8cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose  version 2, as published by the Free Software Foundation.
9cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
10cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose  This program is distributed in the hope it will be useful, but WITHOUT
11cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose  more details.
14cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
15cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose  You should have received a copy of the GNU General Public License along with
16cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose  this program; if not, write to the Free Software Foundation, Inc.,
17cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
19cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose  The full GNU General Public License is included in this distribution in
20cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose  the file called "COPYING".
21cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
22cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose  Contact Information:
23cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
24cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
25cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
26cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose*******************************************************************************/
27cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
28cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose#include "mbx.h"
29b5417bf8e8952401bca69ded67c30ead484af823Stephen Hemminger#include "ixgbevf.h"
30cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
31cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose/**
32cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  ixgbevf_poll_for_msg - Wait for message notification
33cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  @hw: pointer to the HW structure
34cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *
35cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  returns 0 if it successfully received a message notification
36cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose **/
37cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rosestatic s32 ixgbevf_poll_for_msg(struct ixgbe_hw *hw)
38cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose{
39cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	struct ixgbe_mbx_info *mbx = &hw->mbx;
40cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	int countdown = mbx->timeout;
41cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
42cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	while (countdown && mbx->ops.check_for_msg(hw)) {
43cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose		countdown--;
44cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose		udelay(mbx->udelay);
45cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	}
46cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
47cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	/* if we failed, all future posted messages fail until reset */
48cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	if (!countdown)
49cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose		mbx->timeout = 0;
50cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
51cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	return countdown ? 0 : IXGBE_ERR_MBX;
52cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose}
53cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
54cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose/**
55cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  ixgbevf_poll_for_ack - Wait for message acknowledgement
56cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  @hw: pointer to the HW structure
57cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *
58cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  returns 0 if it successfully received a message acknowledgement
59cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose **/
60cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rosestatic s32 ixgbevf_poll_for_ack(struct ixgbe_hw *hw)
61cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose{
62cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	struct ixgbe_mbx_info *mbx = &hw->mbx;
63cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	int countdown = mbx->timeout;
64cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
65cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	while (countdown && mbx->ops.check_for_ack(hw)) {
66cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose		countdown--;
67cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose		udelay(mbx->udelay);
68cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	}
69cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
70cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	/* if we failed, all future posted messages fail until reset */
71cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	if (!countdown)
72cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose		mbx->timeout = 0;
73cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
74cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	return countdown ? 0 : IXGBE_ERR_MBX;
75cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose}
76cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
77cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose/**
78cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  ixgbevf_read_posted_mbx - Wait for message notification and receive message
79cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  @hw: pointer to the HW structure
80cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  @msg: The message buffer
81cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  @size: Length of buffer
82cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *
83cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  returns 0 if it successfully received a message notification and
84cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  copied it into the receive buffer.
85cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose **/
86cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rosestatic s32 ixgbevf_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size)
87cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose{
88cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	struct ixgbe_mbx_info *mbx = &hw->mbx;
89cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	s32 ret_val = IXGBE_ERR_MBX;
90cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
91cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	ret_val = ixgbevf_poll_for_msg(hw);
92cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
93cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	/* if ack received read message, otherwise we timed out */
94cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	if (!ret_val)
95cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose		ret_val = mbx->ops.read(hw, msg, size);
96cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
97cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	return ret_val;
98cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose}
99cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
100cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose/**
101cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  ixgbevf_write_posted_mbx - Write a message to the mailbox, wait for ack
102cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  @hw: pointer to the HW structure
103cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  @msg: The message buffer
104cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  @size: Length of buffer
105cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *
106cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  returns 0 if it successfully copied message into the buffer and
107cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  received an ack to that message within delay * timeout period
108cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose **/
109cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rosestatic s32 ixgbevf_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size)
110cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose{
111cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	struct ixgbe_mbx_info *mbx = &hw->mbx;
112cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	s32 ret_val;
113cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
114cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	/* send msg */
115cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	ret_val = mbx->ops.write(hw, msg, size);
116cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
117cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	/* if msg sent wait until we receive an ack */
118cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	if (!ret_val)
119cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose		ret_val = ixgbevf_poll_for_ack(hw);
120cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
121cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	return ret_val;
122cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose}
123cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
124cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose/**
125cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  ixgbevf_read_v2p_mailbox - read v2p mailbox
126cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  @hw: pointer to the HW structure
127cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *
128cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  This function is used to read the v2p mailbox without losing the read to
129cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  clear status bits.
130cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose **/
131cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rosestatic u32 ixgbevf_read_v2p_mailbox(struct ixgbe_hw *hw)
132cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose{
133cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	u32 v2p_mailbox = IXGBE_READ_REG(hw, IXGBE_VFMAILBOX);
134cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
135cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	v2p_mailbox |= hw->mbx.v2p_mailbox;
136cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	hw->mbx.v2p_mailbox |= v2p_mailbox & IXGBE_VFMAILBOX_R2C_BITS;
137cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
138cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	return v2p_mailbox;
139cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose}
140cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
141cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose/**
142cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  ixgbevf_check_for_bit_vf - Determine if a status bit was set
143cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  @hw: pointer to the HW structure
144cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  @mask: bitmask for bits to be tested and cleared
145cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *
146cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  This function is used to check for the read to clear bits within
147cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  the V2P mailbox.
148cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose **/
149cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rosestatic s32 ixgbevf_check_for_bit_vf(struct ixgbe_hw *hw, u32 mask)
150cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose{
151cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	u32 v2p_mailbox = ixgbevf_read_v2p_mailbox(hw);
152cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	s32 ret_val = IXGBE_ERR_MBX;
153cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
154cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	if (v2p_mailbox & mask)
155cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose		ret_val = 0;
156cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
157cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	hw->mbx.v2p_mailbox &= ~mask;
158cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
159cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	return ret_val;
160cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose}
161cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
162cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose/**
163cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  ixgbevf_check_for_msg_vf - checks to see if the PF has sent mail
164cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  @hw: pointer to the HW structure
165cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *
166cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  returns 0 if the PF has set the Status bit or else ERR_MBX
167cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose **/
168cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rosestatic s32 ixgbevf_check_for_msg_vf(struct ixgbe_hw *hw)
169cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose{
170cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	s32 ret_val = IXGBE_ERR_MBX;
171cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
172cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	if (!ixgbevf_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFSTS)) {
173cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose		ret_val = 0;
174cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose		hw->mbx.stats.reqs++;
175cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	}
176cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
177cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	return ret_val;
178cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose}
179cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
180cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose/**
181cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  ixgbevf_check_for_ack_vf - checks to see if the PF has ACK'd
182cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  @hw: pointer to the HW structure
183cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *
184cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  returns 0 if the PF has set the ACK bit or else ERR_MBX
185cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose **/
186cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rosestatic s32 ixgbevf_check_for_ack_vf(struct ixgbe_hw *hw)
187cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose{
188cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	s32 ret_val = IXGBE_ERR_MBX;
189cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
190cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	if (!ixgbevf_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFACK)) {
191cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose		ret_val = 0;
192cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose		hw->mbx.stats.acks++;
193cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	}
194cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
195cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	return ret_val;
196cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose}
197cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
198cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose/**
199cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  ixgbevf_check_for_rst_vf - checks to see if the PF has reset
200cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  @hw: pointer to the HW structure
201cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *
202cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  returns true if the PF has set the reset done bit or else false
203cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose **/
204cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rosestatic s32 ixgbevf_check_for_rst_vf(struct ixgbe_hw *hw)
205cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose{
206cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	s32 ret_val = IXGBE_ERR_MBX;
207cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
208cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	if (!ixgbevf_check_for_bit_vf(hw, (IXGBE_VFMAILBOX_RSTD |
209cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose					 IXGBE_VFMAILBOX_RSTI))) {
210cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose		ret_val = 0;
211cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose		hw->mbx.stats.rsts++;
212cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	}
213cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
214cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	return ret_val;
215cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose}
216cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
217cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose/**
218cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  ixgbevf_obtain_mbx_lock_vf - obtain mailbox lock
219cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  @hw: pointer to the HW structure
220cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *
221cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  return 0 if we obtained the mailbox lock
222cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose **/
223cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rosestatic s32 ixgbevf_obtain_mbx_lock_vf(struct ixgbe_hw *hw)
224cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose{
225cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	s32 ret_val = IXGBE_ERR_MBX;
226cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
227cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	/* Take ownership of the buffer */
228cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_VFU);
229cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
230cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	/* reserve mailbox for vf use */
231cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	if (ixgbevf_read_v2p_mailbox(hw) & IXGBE_VFMAILBOX_VFU)
232cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose		ret_val = 0;
233cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
234cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	return ret_val;
235cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose}
236cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
237cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose/**
238cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  ixgbevf_write_mbx_vf - Write a message to the mailbox
239cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  @hw: pointer to the HW structure
240cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  @msg: The message buffer
241cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  @size: Length of buffer
242cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *
243cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  returns 0 if it successfully copied message into the buffer
244cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose **/
245cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rosestatic s32 ixgbevf_write_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size)
246cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose{
247cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	s32 ret_val;
248cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	u16 i;
249cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
250cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
251cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	/* lock the mailbox to prevent pf/vf race condition */
252cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	ret_val = ixgbevf_obtain_mbx_lock_vf(hw);
253cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	if (ret_val)
254cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose		goto out_no_write;
255cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
256cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	/* flush msg and acks as we are overwriting the message buffer */
257cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	ixgbevf_check_for_msg_vf(hw);
258cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	ixgbevf_check_for_ack_vf(hw);
259cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
260cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	/* copy the caller specified message to the mailbox memory buffer */
261cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	for (i = 0; i < size; i++)
262cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFMBMEM, i, msg[i]);
263cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
264cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	/* update stats */
265cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	hw->mbx.stats.msgs_tx++;
266cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
267cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	/* Drop VFU and interrupt the PF to tell it a message has been sent */
268cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_REQ);
269cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
270cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Roseout_no_write:
271cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	return ret_val;
272cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose}
273cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
274cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose/**
275cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  ixgbevf_read_mbx_vf - Reads a message from the inbox intended for vf
276cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  @hw: pointer to the HW structure
277cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  @msg: The message buffer
278cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  @size: Length of buffer
279cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *
280bfb9035c98906aafcd3cf22694fba2550997bf53Joe Perches *  returns 0 if it successfully read message from buffer
281cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose **/
282cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rosestatic s32 ixgbevf_read_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size)
283cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose{
284cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	s32 ret_val = 0;
285cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	u16 i;
286cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
287cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	/* lock the mailbox to prevent pf/vf race condition */
288cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	ret_val = ixgbevf_obtain_mbx_lock_vf(hw);
289cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	if (ret_val)
290cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose		goto out_no_read;
291cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
292cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	/* copy the message from the mailbox memory buffer */
293cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	for (i = 0; i < size; i++)
294cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose		msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i);
295cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
296cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	/* Acknowledge receipt and release mailbox, then we're done */
297cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_ACK);
298cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
299cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	/* update stats */
300cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	hw->mbx.stats.msgs_rx++;
301cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
302cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Roseout_no_read:
303cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	return ret_val;
304cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose}
305cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
306cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose/**
307cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  ixgbevf_init_mbx_params_vf - set initial values for vf mailbox
308cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  @hw: pointer to the HW structure
309cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *
310cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose *  Initializes the hw->mbx struct to correct values for vf mailbox
311cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose */
3129ed51657f6ea2a08582d6a9be5404b044972b7e0Emil Tantilovstatic s32 ixgbevf_init_mbx_params_vf(struct ixgbe_hw *hw)
313cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose{
314cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	struct ixgbe_mbx_info *mbx = &hw->mbx;
315cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
316cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	/* start mailbox as timed out and let the reset_hw call set the timeout
317cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	 * value to begin communications */
318cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	mbx->timeout = 0;
319cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	mbx->udelay = IXGBE_VF_MBX_INIT_DELAY;
320cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
321cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	mbx->size = IXGBE_VFMAILBOX_SIZE;
322cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
323cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	mbx->stats.msgs_tx = 0;
324cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	mbx->stats.msgs_rx = 0;
325cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	mbx->stats.reqs = 0;
326cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	mbx->stats.acks = 0;
327cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	mbx->stats.rsts = 0;
328cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
329cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	return 0;
330cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose}
331cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
332b5417bf8e8952401bca69ded67c30ead484af823Stephen Hemmingerconst struct ixgbe_mbx_operations ixgbevf_mbx_ops = {
333cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	.init_params   = ixgbevf_init_mbx_params_vf,
334cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	.read          = ixgbevf_read_mbx_vf,
335cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	.write         = ixgbevf_write_mbx_vf,
336cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	.read_posted   = ixgbevf_read_posted_mbx,
337cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	.write_posted  = ixgbevf_write_posted_mbx,
338cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	.check_for_msg = ixgbevf_check_for_msg_vf,
339cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	.check_for_ack = ixgbevf_check_for_ack_vf,
340cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose	.check_for_rst = ixgbevf_check_for_rst_vf,
341cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose};
342cbf698dbba25741ee1b2e734a6dd4f3070a1706fGreg Rose
343