1 /*******************************************************************************
3 Intel 10 Gigabit PCI Express Linux driver
4 Copyright(c) 1999 - 2011 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 *******************************************************************************/
28 #include <linux/pci.h>
29 #include <linux/delay.h>
30 #include "ixgbe_type.h"
31 #include "ixgbe_common.h"
32 #include "ixgbe_mbx.h"
35 * ixgbe_read_mbx - Reads a message from the mailbox
36 * @hw: pointer to the HW structure
37 * @msg: The message buffer
38 * @size: Length of buffer
39 * @mbx_id: id of mailbox to read
41 * returns SUCCESS if it successfuly read message from buffer
43 s32 ixgbe_read_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
45 struct ixgbe_mbx_info *mbx = &hw->mbx;
46 s32 ret_val = IXGBE_ERR_MBX;
48 /* limit read to size of mailbox */
53 ret_val = mbx->ops.read(hw, msg, size, mbx_id);
59 * ixgbe_write_mbx - Write a message to the mailbox
60 * @hw: pointer to the HW structure
61 * @msg: The message buffer
62 * @size: Length of buffer
63 * @mbx_id: id of mailbox to write
65 * returns SUCCESS if it successfully copied message into the buffer
67 s32 ixgbe_write_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
69 struct ixgbe_mbx_info *mbx = &hw->mbx;
73 ret_val = IXGBE_ERR_MBX;
75 else if (mbx->ops.write)
76 ret_val = mbx->ops.write(hw, msg, size, mbx_id);
82 * ixgbe_check_for_msg - checks to see if someone sent us mail
83 * @hw: pointer to the HW structure
84 * @mbx_id: id of mailbox to check
86 * returns SUCCESS if the Status bit was found or else ERR_MBX
88 s32 ixgbe_check_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
90 struct ixgbe_mbx_info *mbx = &hw->mbx;
91 s32 ret_val = IXGBE_ERR_MBX;
93 if (mbx->ops.check_for_msg)
94 ret_val = mbx->ops.check_for_msg(hw, mbx_id);
100 * ixgbe_check_for_ack - checks to see if someone sent us ACK
101 * @hw: pointer to the HW structure
102 * @mbx_id: id of mailbox to check
104 * returns SUCCESS if the Status bit was found or else ERR_MBX
106 s32 ixgbe_check_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
108 struct ixgbe_mbx_info *mbx = &hw->mbx;
109 s32 ret_val = IXGBE_ERR_MBX;
111 if (mbx->ops.check_for_ack)
112 ret_val = mbx->ops.check_for_ack(hw, mbx_id);
118 * ixgbe_check_for_rst - checks to see if other side has reset
119 * @hw: pointer to the HW structure
120 * @mbx_id: id of mailbox to check
122 * returns SUCCESS if the Status bit was found or else ERR_MBX
124 s32 ixgbe_check_for_rst(struct ixgbe_hw *hw, u16 mbx_id)
126 struct ixgbe_mbx_info *mbx = &hw->mbx;
127 s32 ret_val = IXGBE_ERR_MBX;
129 if (mbx->ops.check_for_rst)
130 ret_val = mbx->ops.check_for_rst(hw, mbx_id);
136 * ixgbe_poll_for_msg - Wait for message notification
137 * @hw: pointer to the HW structure
138 * @mbx_id: id of mailbox to write
140 * returns SUCCESS if it successfully received a message notification
142 static s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
144 struct ixgbe_mbx_info *mbx = &hw->mbx;
145 int countdown = mbx->timeout;
147 if (!countdown || !mbx->ops.check_for_msg)
150 while (countdown && mbx->ops.check_for_msg(hw, mbx_id)) {
154 udelay(mbx->usec_delay);
158 return countdown ? 0 : IXGBE_ERR_MBX;
162 * ixgbe_poll_for_ack - Wait for message acknowledgement
163 * @hw: pointer to the HW structure
164 * @mbx_id: id of mailbox to write
166 * returns SUCCESS if it successfully received a message acknowledgement
168 static s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
170 struct ixgbe_mbx_info *mbx = &hw->mbx;
171 int countdown = mbx->timeout;
173 if (!countdown || !mbx->ops.check_for_ack)
176 while (countdown && mbx->ops.check_for_ack(hw, mbx_id)) {
180 udelay(mbx->usec_delay);
184 return countdown ? 0 : IXGBE_ERR_MBX;
188 * ixgbe_read_posted_mbx - Wait for message notification and receive message
189 * @hw: pointer to the HW structure
190 * @msg: The message buffer
191 * @size: Length of buffer
192 * @mbx_id: id of mailbox to write
194 * returns SUCCESS if it successfully received a message notification and
195 * copied it into the receive buffer.
197 static s32 ixgbe_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size,
200 struct ixgbe_mbx_info *mbx = &hw->mbx;
201 s32 ret_val = IXGBE_ERR_MBX;
206 ret_val = ixgbe_poll_for_msg(hw, mbx_id);
208 /* if ack received read message, otherwise we timed out */
210 ret_val = mbx->ops.read(hw, msg, size, mbx_id);
216 * ixgbe_write_posted_mbx - Write a message to the mailbox, wait for ack
217 * @hw: pointer to the HW structure
218 * @msg: The message buffer
219 * @size: Length of buffer
220 * @mbx_id: id of mailbox to write
222 * returns SUCCESS if it successfully copied message into the buffer and
223 * received an ack to that message within delay * timeout period
225 static s32 ixgbe_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size,
228 struct ixgbe_mbx_info *mbx = &hw->mbx;
229 s32 ret_val = IXGBE_ERR_MBX;
231 /* exit if either we can't write or there isn't a defined timeout */
232 if (!mbx->ops.write || !mbx->timeout)
236 ret_val = mbx->ops.write(hw, msg, size, mbx_id);
238 /* if msg sent wait until we receive an ack */
240 ret_val = ixgbe_poll_for_ack(hw, mbx_id);
245 static s32 ixgbe_check_for_bit_pf(struct ixgbe_hw *hw, u32 mask, s32 index)
247 u32 mbvficr = IXGBE_READ_REG(hw, IXGBE_MBVFICR(index));
248 s32 ret_val = IXGBE_ERR_MBX;
250 if (mbvficr & mask) {
252 IXGBE_WRITE_REG(hw, IXGBE_MBVFICR(index), mask);
259 * ixgbe_check_for_msg_pf - checks to see if the VF has sent mail
260 * @hw: pointer to the HW structure
261 * @vf_number: the VF index
263 * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
265 static s32 ixgbe_check_for_msg_pf(struct ixgbe_hw *hw, u16 vf_number)
267 s32 ret_val = IXGBE_ERR_MBX;
268 s32 index = IXGBE_MBVFICR_INDEX(vf_number);
269 u32 vf_bit = vf_number % 16;
271 if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFREQ_VF1 << vf_bit,
274 hw->mbx.stats.reqs++;
281 * ixgbe_check_for_ack_pf - checks to see if the VF has ACKed
282 * @hw: pointer to the HW structure
283 * @vf_number: the VF index
285 * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
287 static s32 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_number)
289 s32 ret_val = IXGBE_ERR_MBX;
290 s32 index = IXGBE_MBVFICR_INDEX(vf_number);
291 u32 vf_bit = vf_number % 16;
293 if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFACK_VF1 << vf_bit,
296 hw->mbx.stats.acks++;
303 * ixgbe_check_for_rst_pf - checks to see if the VF has reset
304 * @hw: pointer to the HW structure
305 * @vf_number: the VF index
307 * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
309 static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_number)
311 u32 reg_offset = (vf_number < 32) ? 0 : 1;
312 u32 vf_shift = vf_number % 32;
314 s32 ret_val = IXGBE_ERR_MBX;
316 switch (hw->mac.type) {
317 case ixgbe_mac_82599EB:
318 vflre = IXGBE_READ_REG(hw, IXGBE_VFLRE(reg_offset));
321 vflre = IXGBE_READ_REG(hw, IXGBE_VFLREC(reg_offset));
327 if (vflre & (1 << vf_shift)) {
329 IXGBE_WRITE_REG(hw, IXGBE_VFLREC(reg_offset), (1 << vf_shift));
330 hw->mbx.stats.rsts++;
337 * ixgbe_obtain_mbx_lock_pf - obtain mailbox lock
338 * @hw: pointer to the HW structure
339 * @vf_number: the VF index
341 * return SUCCESS if we obtained the mailbox lock
343 static s32 ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_number)
345 s32 ret_val = IXGBE_ERR_MBX;
348 /* Take ownership of the buffer */
349 IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_PFU);
351 /* reserve mailbox for vf use */
352 p2v_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_number));
353 if (p2v_mailbox & IXGBE_PFMAILBOX_PFU)
360 * ixgbe_write_mbx_pf - Places a message in the mailbox
361 * @hw: pointer to the HW structure
362 * @msg: The message buffer
363 * @size: Length of buffer
364 * @vf_number: the VF index
366 * returns SUCCESS if it successfully copied message into the buffer
368 static s32 ixgbe_write_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
374 /* lock the mailbox to prevent pf/vf race condition */
375 ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number);
379 /* flush msg and acks as we are overwriting the message buffer */
380 ixgbe_check_for_msg_pf(hw, vf_number);
381 ixgbe_check_for_ack_pf(hw, vf_number);
383 /* copy the caller specified message to the mailbox memory buffer */
384 for (i = 0; i < size; i++)
385 IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i, msg[i]);
387 /* Interrupt VF to tell it a message has been sent and release buffer*/
388 IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_STS);
391 hw->mbx.stats.msgs_tx++;
399 * ixgbe_read_mbx_pf - Read a message from the mailbox
400 * @hw: pointer to the HW structure
401 * @msg: The message buffer
402 * @size: Length of buffer
403 * @vf_number: the VF index
405 * This function copies a message from the mailbox buffer to the caller's
406 * memory buffer. The presumption is that the caller knows that there was
407 * a message due to a VF request so no polling for message is needed.
409 static s32 ixgbe_read_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
415 /* lock the mailbox to prevent pf/vf race condition */
416 ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number);
420 /* copy the message to the mailbox memory buffer */
421 for (i = 0; i < size; i++)
422 msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i);
424 /* Acknowledge the message and release buffer */
425 IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_ACK);
428 hw->mbx.stats.msgs_rx++;
434 #ifdef CONFIG_PCI_IOV
436 * ixgbe_init_mbx_params_pf - set initial values for pf mailbox
437 * @hw: pointer to the HW structure
439 * Initializes the hw->mbx struct to correct values for pf mailbox
441 void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw)
443 struct ixgbe_mbx_info *mbx = &hw->mbx;
445 if (hw->mac.type != ixgbe_mac_82599EB &&
446 hw->mac.type != ixgbe_mac_X540)
452 mbx->stats.msgs_tx = 0;
453 mbx->stats.msgs_rx = 0;
458 mbx->size = IXGBE_VFMAILBOX_SIZE;
460 #endif /* CONFIG_PCI_IOV */
462 struct ixgbe_mbx_operations mbx_ops_generic = {
463 .read = ixgbe_read_mbx_pf,
464 .write = ixgbe_write_mbx_pf,
465 .read_posted = ixgbe_read_posted_mbx,
466 .write_posted = ixgbe_write_posted_mbx,
467 .check_for_msg = ixgbe_check_for_msg_pf,
468 .check_for_ack = ixgbe_check_for_ack_pf,
469 .check_for_rst = ixgbe_check_for_rst_pf,