1 /*******************************************************************************
3 Intel 10 Gigabit PCI Express Linux driver
4 Copyright(c) 1999 - 2016 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".
25 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27 *******************************************************************************/
29 #include <linux/pci.h>
30 #include <linux/delay.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 successfully 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;
47 /* limit read to size of mailbox */
54 return mbx->ops->read(hw, msg, size, mbx_id);
58 * ixgbe_write_mbx - Write a message to the mailbox
59 * @hw: pointer to the HW structure
60 * @msg: The message buffer
61 * @size: Length of buffer
62 * @mbx_id: id of mailbox to write
64 * returns SUCCESS if it successfully copied message into the buffer
66 s32 ixgbe_write_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
68 struct ixgbe_mbx_info *mbx = &hw->mbx;
76 return mbx->ops->write(hw, msg, size, mbx_id);
80 * ixgbe_check_for_msg - checks to see if someone sent us mail
81 * @hw: pointer to the HW structure
82 * @mbx_id: id of mailbox to check
84 * returns SUCCESS if the Status bit was found or else ERR_MBX
86 s32 ixgbe_check_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
88 struct ixgbe_mbx_info *mbx = &hw->mbx;
93 return mbx->ops->check_for_msg(hw, mbx_id);
97 * ixgbe_check_for_ack - checks to see if someone sent us ACK
98 * @hw: pointer to the HW structure
99 * @mbx_id: id of mailbox to check
101 * returns SUCCESS if the Status bit was found or else ERR_MBX
103 s32 ixgbe_check_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
105 struct ixgbe_mbx_info *mbx = &hw->mbx;
108 return IXGBE_ERR_MBX;
110 return mbx->ops->check_for_ack(hw, mbx_id);
114 * ixgbe_check_for_rst - checks to see if other side has reset
115 * @hw: pointer to the HW structure
116 * @mbx_id: id of mailbox to check
118 * returns SUCCESS if the Status bit was found or else ERR_MBX
120 s32 ixgbe_check_for_rst(struct ixgbe_hw *hw, u16 mbx_id)
122 struct ixgbe_mbx_info *mbx = &hw->mbx;
125 return IXGBE_ERR_MBX;
127 return mbx->ops->check_for_rst(hw, mbx_id);
131 * ixgbe_poll_for_msg - Wait for message notification
132 * @hw: pointer to the HW structure
133 * @mbx_id: id of mailbox to write
135 * returns SUCCESS if it successfully received a message notification
137 static s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
139 struct ixgbe_mbx_info *mbx = &hw->mbx;
140 int countdown = mbx->timeout;
142 if (!countdown || !mbx->ops)
143 return IXGBE_ERR_MBX;
145 while (mbx->ops->check_for_msg(hw, mbx_id)) {
148 return IXGBE_ERR_MBX;
149 udelay(mbx->usec_delay);
156 * ixgbe_poll_for_ack - Wait for message acknowledgement
157 * @hw: pointer to the HW structure
158 * @mbx_id: id of mailbox to write
160 * returns SUCCESS if it successfully received a message acknowledgement
162 static s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
164 struct ixgbe_mbx_info *mbx = &hw->mbx;
165 int countdown = mbx->timeout;
167 if (!countdown || !mbx->ops)
168 return IXGBE_ERR_MBX;
170 while (mbx->ops->check_for_ack(hw, mbx_id)) {
173 return IXGBE_ERR_MBX;
174 udelay(mbx->usec_delay);
181 * ixgbe_read_posted_mbx - Wait for message notification and receive message
182 * @hw: pointer to the HW structure
183 * @msg: The message buffer
184 * @size: Length of buffer
185 * @mbx_id: id of mailbox to write
187 * returns SUCCESS if it successfully received a message notification and
188 * copied it into the receive buffer.
190 static s32 ixgbe_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size,
193 struct ixgbe_mbx_info *mbx = &hw->mbx;
197 return IXGBE_ERR_MBX;
199 ret_val = ixgbe_poll_for_msg(hw, mbx_id);
203 /* if ack received read message */
204 return mbx->ops->read(hw, msg, size, mbx_id);
208 * ixgbe_write_posted_mbx - Write a message to the mailbox, wait for ack
209 * @hw: pointer to the HW structure
210 * @msg: The message buffer
211 * @size: Length of buffer
212 * @mbx_id: id of mailbox to write
214 * returns SUCCESS if it successfully copied message into the buffer and
215 * received an ack to that message within delay * timeout period
217 static s32 ixgbe_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size,
220 struct ixgbe_mbx_info *mbx = &hw->mbx;
223 /* exit if either we can't write or there isn't a defined timeout */
224 if (!mbx->ops || !mbx->timeout)
225 return IXGBE_ERR_MBX;
228 ret_val = mbx->ops->write(hw, msg, size, mbx_id);
232 /* if msg sent wait until we receive an ack */
233 return ixgbe_poll_for_ack(hw, mbx_id);
236 static s32 ixgbe_check_for_bit_pf(struct ixgbe_hw *hw, u32 mask, s32 index)
238 u32 mbvficr = IXGBE_READ_REG(hw, IXGBE_MBVFICR(index));
240 if (mbvficr & mask) {
241 IXGBE_WRITE_REG(hw, IXGBE_MBVFICR(index), mask);
245 return IXGBE_ERR_MBX;
249 * ixgbe_check_for_msg_pf - checks to see if the VF has sent mail
250 * @hw: pointer to the HW structure
251 * @vf_number: the VF index
253 * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
255 static s32 ixgbe_check_for_msg_pf(struct ixgbe_hw *hw, u16 vf_number)
257 s32 index = IXGBE_MBVFICR_INDEX(vf_number);
258 u32 vf_bit = vf_number % 16;
260 if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFREQ_VF1 << vf_bit,
262 hw->mbx.stats.reqs++;
266 return IXGBE_ERR_MBX;
270 * ixgbe_check_for_ack_pf - checks to see if the VF has ACKed
271 * @hw: pointer to the HW structure
272 * @vf_number: the VF index
274 * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
276 static s32 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_number)
278 s32 index = IXGBE_MBVFICR_INDEX(vf_number);
279 u32 vf_bit = vf_number % 16;
281 if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFACK_VF1 << vf_bit,
283 hw->mbx.stats.acks++;
287 return IXGBE_ERR_MBX;
291 * ixgbe_check_for_rst_pf - checks to see if the VF has reset
292 * @hw: pointer to the HW structure
293 * @vf_number: the VF index
295 * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
297 static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_number)
299 u32 reg_offset = (vf_number < 32) ? 0 : 1;
300 u32 vf_shift = vf_number % 32;
303 switch (hw->mac.type) {
304 case ixgbe_mac_82599EB:
305 vflre = IXGBE_READ_REG(hw, IXGBE_VFLRE(reg_offset));
309 case ixgbe_mac_X550EM_x:
310 case ixgbe_mac_x550em_a:
311 vflre = IXGBE_READ_REG(hw, IXGBE_VFLREC(reg_offset));
317 if (vflre & BIT(vf_shift)) {
318 IXGBE_WRITE_REG(hw, IXGBE_VFLREC(reg_offset), BIT(vf_shift));
319 hw->mbx.stats.rsts++;
323 return IXGBE_ERR_MBX;
327 * ixgbe_obtain_mbx_lock_pf - obtain mailbox lock
328 * @hw: pointer to the HW structure
329 * @vf_number: the VF index
331 * return SUCCESS if we obtained the mailbox lock
333 static s32 ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_number)
337 /* Take ownership of the buffer */
338 IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_PFU);
340 /* reserve mailbox for vf use */
341 p2v_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_number));
342 if (p2v_mailbox & IXGBE_PFMAILBOX_PFU)
345 return IXGBE_ERR_MBX;
349 * ixgbe_write_mbx_pf - Places a message in the mailbox
350 * @hw: pointer to the HW structure
351 * @msg: The message buffer
352 * @size: Length of buffer
353 * @vf_number: the VF index
355 * returns SUCCESS if it successfully copied message into the buffer
357 static s32 ixgbe_write_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
363 /* lock the mailbox to prevent pf/vf race condition */
364 ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number);
368 /* flush msg and acks as we are overwriting the message buffer */
369 ixgbe_check_for_msg_pf(hw, vf_number);
370 ixgbe_check_for_ack_pf(hw, vf_number);
372 /* copy the caller specified message to the mailbox memory buffer */
373 for (i = 0; i < size; i++)
374 IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i, msg[i]);
376 /* Interrupt VF to tell it a message has been sent and release buffer*/
377 IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_STS);
380 hw->mbx.stats.msgs_tx++;
386 * ixgbe_read_mbx_pf - Read a message from the mailbox
387 * @hw: pointer to the HW structure
388 * @msg: The message buffer
389 * @size: Length of buffer
390 * @vf_number: the VF index
392 * This function copies a message from the mailbox buffer to the caller's
393 * memory buffer. The presumption is that the caller knows that there was
394 * a message due to a VF request so no polling for message is needed.
396 static s32 ixgbe_read_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
402 /* lock the mailbox to prevent pf/vf race condition */
403 ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number);
407 /* copy the message to the mailbox memory buffer */
408 for (i = 0; i < size; i++)
409 msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i);
411 /* Acknowledge the message and release buffer */
412 IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_ACK);
415 hw->mbx.stats.msgs_rx++;
420 #ifdef CONFIG_PCI_IOV
422 * ixgbe_init_mbx_params_pf - set initial values for pf mailbox
423 * @hw: pointer to the HW structure
425 * Initializes the hw->mbx struct to correct values for pf mailbox
427 void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw)
429 struct ixgbe_mbx_info *mbx = &hw->mbx;
431 if (hw->mac.type != ixgbe_mac_82599EB &&
432 hw->mac.type != ixgbe_mac_X550 &&
433 hw->mac.type != ixgbe_mac_X550EM_x &&
434 hw->mac.type != ixgbe_mac_x550em_a &&
435 hw->mac.type != ixgbe_mac_X540)
441 mbx->stats.msgs_tx = 0;
442 mbx->stats.msgs_rx = 0;
447 mbx->size = IXGBE_VFMAILBOX_SIZE;
449 #endif /* CONFIG_PCI_IOV */
451 const struct ixgbe_mbx_operations mbx_ops_generic = {
452 .read = ixgbe_read_mbx_pf,
453 .write = ixgbe_write_mbx_pf,
454 .read_posted = ixgbe_read_posted_mbx,
455 .write_posted = ixgbe_write_posted_mbx,
456 .check_for_msg = ixgbe_check_for_msg_pf,
457 .check_for_ack = ixgbe_check_for_ack_pf,
458 .check_for_rst = ixgbe_check_for_rst_pf,