1 /*******************************************************************************
3 Intel 82599 Virtual Function driver
4 Copyright(c) 1999 - 2012 Intel Corporation.
6 This program is free software; you can redistribute it and/or modify it
7 under the terms and conditions of the GNU General Public License,
8 version 2, as published by the Free Software Foundation.
10 This program is distributed in the hope it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 You should have received a copy of the GNU General Public License along with
16 this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
19 The full GNU General Public License is included in this distribution in
20 the file called "COPYING".
24 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
26 *******************************************************************************/
32 * ixgbevf_poll_for_msg - Wait for message notification
33 * @hw: pointer to the HW structure
35 * returns 0 if it successfully received a message notification
37 static s32 ixgbevf_poll_for_msg(struct ixgbe_hw *hw)
39 struct ixgbe_mbx_info *mbx = &hw->mbx;
40 int countdown = mbx->timeout;
42 while (countdown && mbx->ops.check_for_msg(hw)) {
47 /* if we failed, all future posted messages fail until reset */
51 return countdown ? 0 : IXGBE_ERR_MBX;
55 * ixgbevf_poll_for_ack - Wait for message acknowledgement
56 * @hw: pointer to the HW structure
58 * returns 0 if it successfully received a message acknowledgement
60 static s32 ixgbevf_poll_for_ack(struct ixgbe_hw *hw)
62 struct ixgbe_mbx_info *mbx = &hw->mbx;
63 int countdown = mbx->timeout;
65 while (countdown && mbx->ops.check_for_ack(hw)) {
70 /* if we failed, all future posted messages fail until reset */
74 return countdown ? 0 : IXGBE_ERR_MBX;
78 * ixgbevf_read_posted_mbx - Wait for message notification and receive message
79 * @hw: pointer to the HW structure
80 * @msg: The message buffer
81 * @size: Length of buffer
83 * returns 0 if it successfully received a message notification and
84 * copied it into the receive buffer.
86 static s32 ixgbevf_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size)
88 struct ixgbe_mbx_info *mbx = &hw->mbx;
89 s32 ret_val = -IXGBE_ERR_MBX;
94 ret_val = ixgbevf_poll_for_msg(hw);
96 /* if ack received read message, otherwise we timed out */
98 ret_val = mbx->ops.read(hw, msg, size);
104 * ixgbevf_write_posted_mbx - Write a message to the mailbox, wait for ack
105 * @hw: pointer to the HW structure
106 * @msg: The message buffer
107 * @size: Length of buffer
109 * returns 0 if it successfully copied message into the buffer and
110 * received an ack to that message within delay * timeout period
112 static s32 ixgbevf_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size)
114 struct ixgbe_mbx_info *mbx = &hw->mbx;
115 s32 ret_val = -IXGBE_ERR_MBX;
117 /* exit if either we can't write or there isn't a defined timeout */
118 if (!mbx->ops.write || !mbx->timeout)
122 ret_val = mbx->ops.write(hw, msg, size);
124 /* if msg sent wait until we receive an ack */
126 ret_val = ixgbevf_poll_for_ack(hw);
132 * ixgbevf_read_v2p_mailbox - read v2p mailbox
133 * @hw: pointer to the HW structure
135 * This function is used to read the v2p mailbox without losing the read to
138 static u32 ixgbevf_read_v2p_mailbox(struct ixgbe_hw *hw)
140 u32 v2p_mailbox = IXGBE_READ_REG(hw, IXGBE_VFMAILBOX);
142 v2p_mailbox |= hw->mbx.v2p_mailbox;
143 hw->mbx.v2p_mailbox |= v2p_mailbox & IXGBE_VFMAILBOX_R2C_BITS;
149 * ixgbevf_check_for_bit_vf - Determine if a status bit was set
150 * @hw: pointer to the HW structure
151 * @mask: bitmask for bits to be tested and cleared
153 * This function is used to check for the read to clear bits within
156 static s32 ixgbevf_check_for_bit_vf(struct ixgbe_hw *hw, u32 mask)
158 u32 v2p_mailbox = ixgbevf_read_v2p_mailbox(hw);
159 s32 ret_val = IXGBE_ERR_MBX;
161 if (v2p_mailbox & mask)
164 hw->mbx.v2p_mailbox &= ~mask;
170 * ixgbevf_check_for_msg_vf - checks to see if the PF has sent mail
171 * @hw: pointer to the HW structure
173 * returns 0 if the PF has set the Status bit or else ERR_MBX
175 static s32 ixgbevf_check_for_msg_vf(struct ixgbe_hw *hw)
177 s32 ret_val = IXGBE_ERR_MBX;
179 if (!ixgbevf_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFSTS)) {
181 hw->mbx.stats.reqs++;
188 * ixgbevf_check_for_ack_vf - checks to see if the PF has ACK'd
189 * @hw: pointer to the HW structure
191 * returns 0 if the PF has set the ACK bit or else ERR_MBX
193 static s32 ixgbevf_check_for_ack_vf(struct ixgbe_hw *hw)
195 s32 ret_val = IXGBE_ERR_MBX;
197 if (!ixgbevf_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFACK)) {
199 hw->mbx.stats.acks++;
206 * ixgbevf_check_for_rst_vf - checks to see if the PF has reset
207 * @hw: pointer to the HW structure
209 * returns true if the PF has set the reset done bit or else false
211 static s32 ixgbevf_check_for_rst_vf(struct ixgbe_hw *hw)
213 s32 ret_val = IXGBE_ERR_MBX;
215 if (!ixgbevf_check_for_bit_vf(hw, (IXGBE_VFMAILBOX_RSTD |
216 IXGBE_VFMAILBOX_RSTI))) {
218 hw->mbx.stats.rsts++;
225 * ixgbevf_obtain_mbx_lock_vf - obtain mailbox lock
226 * @hw: pointer to the HW structure
228 * return 0 if we obtained the mailbox lock
230 static s32 ixgbevf_obtain_mbx_lock_vf(struct ixgbe_hw *hw)
232 s32 ret_val = IXGBE_ERR_MBX;
234 /* Take ownership of the buffer */
235 IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_VFU);
237 /* reserve mailbox for vf use */
238 if (ixgbevf_read_v2p_mailbox(hw) & IXGBE_VFMAILBOX_VFU)
245 * ixgbevf_write_mbx_vf - Write a message to the mailbox
246 * @hw: pointer to the HW structure
247 * @msg: The message buffer
248 * @size: Length of buffer
250 * returns 0 if it successfully copied message into the buffer
252 static s32 ixgbevf_write_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size)
258 /* lock the mailbox to prevent pf/vf race condition */
259 ret_val = ixgbevf_obtain_mbx_lock_vf(hw);
263 /* flush msg and acks as we are overwriting the message buffer */
264 ixgbevf_check_for_msg_vf(hw);
265 ixgbevf_check_for_ack_vf(hw);
267 /* copy the caller specified message to the mailbox memory buffer */
268 for (i = 0; i < size; i++)
269 IXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFMBMEM, i, msg[i]);
272 hw->mbx.stats.msgs_tx++;
274 /* Drop VFU and interrupt the PF to tell it a message has been sent */
275 IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_REQ);
282 * ixgbevf_read_mbx_vf - Reads a message from the inbox intended for vf
283 * @hw: pointer to the HW structure
284 * @msg: The message buffer
285 * @size: Length of buffer
287 * returns 0 if it successfully read message from buffer
289 static s32 ixgbevf_read_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size)
294 /* lock the mailbox to prevent pf/vf race condition */
295 ret_val = ixgbevf_obtain_mbx_lock_vf(hw);
299 /* copy the message from the mailbox memory buffer */
300 for (i = 0; i < size; i++)
301 msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i);
303 /* Acknowledge receipt and release mailbox, then we're done */
304 IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_ACK);
307 hw->mbx.stats.msgs_rx++;
314 * ixgbevf_init_mbx_params_vf - set initial values for vf mailbox
315 * @hw: pointer to the HW structure
317 * Initializes the hw->mbx struct to correct values for vf mailbox
319 static s32 ixgbevf_init_mbx_params_vf(struct ixgbe_hw *hw)
321 struct ixgbe_mbx_info *mbx = &hw->mbx;
323 /* start mailbox as timed out and let the reset_hw call set the timeout
324 * value to begin communications */
326 mbx->udelay = IXGBE_VF_MBX_INIT_DELAY;
328 mbx->size = IXGBE_VFMAILBOX_SIZE;
330 mbx->stats.msgs_tx = 0;
331 mbx->stats.msgs_rx = 0;
339 const struct ixgbe_mbx_operations ixgbevf_mbx_ops = {
340 .init_params = ixgbevf_init_mbx_params_vf,
341 .read = ixgbevf_read_mbx_vf,
342 .write = ixgbevf_write_mbx_vf,
343 .read_posted = ixgbevf_read_posted_mbx,
344 .write_posted = ixgbevf_write_posted_mbx,
345 .check_for_msg = ixgbevf_check_for_msg_vf,
346 .check_for_ack = ixgbevf_check_for_ack_vf,
347 .check_for_rst = ixgbevf_check_for_rst_vf,