1 /******************************************************************************
3 Copyright (c) 2001-2017, Intel Corporation
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met:
9 1. Redistributions of source code must retain the above copyright notice,
10 this list of conditions and the following disclaimer.
12 2. Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
16 3. Neither the name of the Intel Corporation nor the names of its
17 contributors may be used to endorse or promote products derived from
18 this software without specific prior written permission.
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 POSSIBILITY OF SUCH DAMAGE.
32 ******************************************************************************/
39 * ixgbe_poll_for_msg - Wait for message notification
40 * @hw: pointer to the HW structure
41 * @mbx_id: id of mailbox to write
43 * returns SUCCESS if it successfully received a message notification
45 static s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
47 struct ixgbe_mbx_info *mbx = &hw->mbx;
48 int countdown = mbx->timeout;
50 DEBUGFUNC("ixgbe_poll_for_msg");
52 if (!countdown || !mbx->ops.check_for_msg)
55 while (countdown && mbx->ops.check_for_msg(hw, mbx_id)) {
59 usec_delay(mbx->usec_delay);
63 ERROR_REPORT2(IXGBE_ERROR_POLLING,
64 "Polling for VF%d mailbox message timedout", mbx_id);
67 return countdown ? IXGBE_SUCCESS : IXGBE_ERR_MBX;
71 * ixgbe_poll_for_ack - Wait for message acknowledgement
72 * @hw: pointer to the HW structure
73 * @mbx_id: id of mailbox to write
75 * returns SUCCESS if it successfully received a message acknowledgement
77 static s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
79 struct ixgbe_mbx_info *mbx = &hw->mbx;
80 int countdown = mbx->timeout;
82 DEBUGFUNC("ixgbe_poll_for_ack");
84 if (!countdown || !mbx->ops.check_for_ack)
87 while (countdown && mbx->ops.check_for_ack(hw, mbx_id)) {
91 usec_delay(mbx->usec_delay);
95 ERROR_REPORT2(IXGBE_ERROR_POLLING,
96 "Polling for VF%d mailbox ack timedout", mbx_id);
99 return countdown ? IXGBE_SUCCESS : IXGBE_ERR_MBX;
103 * ixgbe_read_posted_mbx - Wait for message notification and receive message
104 * @hw: pointer to the HW structure
105 * @msg: The message buffer
106 * @size: Length of buffer
107 * @mbx_id: id of mailbox to write
109 * returns SUCCESS if it successfully received a message notification and
110 * copied it into the receive buffer.
112 static s32 ixgbe_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size,
115 struct ixgbe_mbx_info *mbx = &hw->mbx;
116 s32 ret_val = IXGBE_ERR_MBX;
118 DEBUGFUNC("ixgbe_read_posted_mbx");
123 ret_val = ixgbe_poll_for_msg(hw, mbx_id);
125 /* if ack received read message, otherwise we timed out */
127 ret_val = mbx->ops.read(hw, msg, size, mbx_id);
133 * ixgbe_write_posted_mbx - Write a message to the mailbox, wait for ack
134 * @hw: pointer to the HW structure
135 * @msg: The message buffer
136 * @size: Length of buffer
137 * @mbx_id: id of mailbox to write
139 * returns SUCCESS if it successfully copied message into the buffer and
140 * received an ack to that message within delay * timeout period
142 static s32 ixgbe_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size,
145 struct ixgbe_mbx_info *mbx = &hw->mbx;
146 s32 ret_val = IXGBE_ERR_MBX;
148 DEBUGFUNC("ixgbe_write_posted_mbx");
150 /* exit if either we can't write or there isn't a defined timeout */
151 if (!mbx->ops.write || !mbx->timeout)
155 ret_val = mbx->ops.write(hw, msg, size, mbx_id);
157 /* if msg sent wait until we receive an ack */
159 ret_val = ixgbe_poll_for_ack(hw, mbx_id);
165 * ixv_init_mbx_ops_generic - Initialize MB function pointers
166 * @hw: pointer to the HW structure
168 * Setups up the mailbox read and write message function pointers
170 void ixv_init_mbx_ops_generic(struct ixgbe_hw *hw)
172 struct ixgbe_mbx_info *mbx = &hw->mbx;
174 mbx->ops.read_posted = ixgbe_read_posted_mbx;
175 mbx->ops.write_posted = ixgbe_write_posted_mbx;
179 * ixgbe_read_v2p_mailbox - read v2p mailbox
180 * @hw: pointer to the HW structure
182 * This function is used to read the v2p mailbox without losing the read to
185 static u32 ixgbe_read_v2p_mailbox(struct ixgbe_hw *hw)
187 u32 v2p_mailbox = IXGBE_READ_REG(hw, IXGBE_VFMAILBOX);
189 v2p_mailbox |= hw->mbx.v2p_mailbox;
190 hw->mbx.v2p_mailbox |= v2p_mailbox & IXGBE_VFMAILBOX_R2C_BITS;
196 * ixgbe_check_for_bit_vf - Determine if a status bit was set
197 * @hw: pointer to the HW structure
198 * @mask: bitmask for bits to be tested and cleared
200 * This function is used to check for the read to clear bits within
203 static s32 ixgbe_check_for_bit_vf(struct ixgbe_hw *hw, u32 mask)
205 u32 v2p_mailbox = ixgbe_read_v2p_mailbox(hw);
206 s32 ret_val = IXGBE_ERR_MBX;
208 if (v2p_mailbox & mask)
209 ret_val = IXGBE_SUCCESS;
211 hw->mbx.v2p_mailbox &= ~mask;
217 * ixgbe_check_for_msg_vf - checks to see if the PF has sent mail
218 * @hw: pointer to the HW structure
219 * @mbx_id: id of mailbox to check
221 * returns SUCCESS if the PF has set the Status bit or else ERR_MBX
223 static s32 ixgbe_check_for_msg_vf(struct ixgbe_hw *hw, u16 mbx_id)
225 s32 ret_val = IXGBE_ERR_MBX;
227 UNREFERENCED_1PARAMETER(mbx_id);
228 DEBUGFUNC("ixgbe_check_for_msg_vf");
230 if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFSTS)) {
231 ret_val = IXGBE_SUCCESS;
232 hw->mbx.stats.reqs++;
239 * ixgbe_check_for_ack_vf - checks to see if the PF has ACK'd
240 * @hw: pointer to the HW structure
241 * @mbx_id: id of mailbox to check
243 * returns SUCCESS if the PF has set the ACK bit or else ERR_MBX
245 static s32 ixgbe_check_for_ack_vf(struct ixgbe_hw *hw, u16 mbx_id)
247 s32 ret_val = IXGBE_ERR_MBX;
249 UNREFERENCED_1PARAMETER(mbx_id);
250 DEBUGFUNC("ixgbe_check_for_ack_vf");
252 if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFACK)) {
253 ret_val = IXGBE_SUCCESS;
254 hw->mbx.stats.acks++;
261 * ixgbe_check_for_rst_vf - checks to see if the PF has reset
262 * @hw: pointer to the HW structure
263 * @mbx_id: id of mailbox to check
265 * returns TRUE if the PF has set the reset done bit or else FALSE
267 static s32 ixgbe_check_for_rst_vf(struct ixgbe_hw *hw, u16 mbx_id)
269 s32 ret_val = IXGBE_ERR_MBX;
271 UNREFERENCED_1PARAMETER(mbx_id);
272 DEBUGFUNC("ixgbe_check_for_rst_vf");
274 if (!ixgbe_check_for_bit_vf(hw, (IXGBE_VFMAILBOX_RSTD |
275 IXGBE_VFMAILBOX_RSTI))) {
276 ret_val = IXGBE_SUCCESS;
277 hw->mbx.stats.rsts++;
284 * ixgbe_obtain_mbx_lock_vf - obtain mailbox lock
285 * @hw: pointer to the HW structure
287 * return SUCCESS if we obtained the mailbox lock
289 static s32 ixgbe_obtain_mbx_lock_vf(struct ixgbe_hw *hw)
291 s32 ret_val = IXGBE_ERR_MBX;
293 DEBUGFUNC("ixgbe_obtain_mbx_lock_vf");
295 /* Take ownership of the buffer */
296 IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_VFU);
298 /* reserve mailbox for vf use */
299 if (ixgbe_read_v2p_mailbox(hw) & IXGBE_VFMAILBOX_VFU)
300 ret_val = IXGBE_SUCCESS;
306 * ixgbe_write_mbx_vf - Write a message to the mailbox
307 * @hw: pointer to the HW structure
308 * @msg: The message buffer
309 * @size: Length of buffer
310 * @mbx_id: id of mailbox to write
312 * returns SUCCESS if it successfully copied message into the buffer
314 static s32 ixgbe_write_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,
320 UNREFERENCED_1PARAMETER(mbx_id);
322 DEBUGFUNC("ixgbe_write_mbx_vf");
324 /* lock the mailbox to prevent pf/vf race condition */
325 ret_val = ixgbe_obtain_mbx_lock_vf(hw);
329 /* flush msg and acks as we are overwriting the message buffer */
330 ixgbe_check_for_msg_vf(hw, 0);
331 ixgbe_check_for_ack_vf(hw, 0);
333 /* copy the caller specified message to the mailbox memory buffer */
334 for (i = 0; i < size; i++)
335 IXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFMBMEM, i, msg[i]);
338 hw->mbx.stats.msgs_tx++;
340 /* Drop VFU and interrupt the PF to tell it a message has been sent */
341 IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_REQ);
348 * ixgbe_read_mbx_vf - Reads a message from the inbox intended for vf
349 * @hw: pointer to the HW structure
350 * @msg: The message buffer
351 * @size: Length of buffer
352 * @mbx_id: id of mailbox to read
354 * returns SUCCESS if it successfuly read message from buffer
356 static s32 ixgbe_read_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,
359 s32 ret_val = IXGBE_SUCCESS;
362 DEBUGFUNC("ixgbe_read_mbx_vf");
363 UNREFERENCED_1PARAMETER(mbx_id);
365 /* lock the mailbox to prevent pf/vf race condition */
366 ret_val = ixgbe_obtain_mbx_lock_vf(hw);
370 /* copy the message from the mailbox memory buffer */
371 for (i = 0; i < size; i++)
372 msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i);
374 /* Acknowledge receipt and release mailbox, then we're done */
375 IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_ACK);
378 hw->mbx.stats.msgs_rx++;
385 * ixv_init_mbx_params_vf - set initial values for vf mailbox
386 * @hw: pointer to the HW structure
388 * Initializes the hw->mbx struct to correct values for vf mailbox
390 void ixv_init_mbx_params_vf(struct ixgbe_hw *hw)
392 struct ixgbe_mbx_info *mbx = &hw->mbx;
394 /* start mailbox as timed out and let the reset_hw call set the timeout
395 * value to begin communications */
397 mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;
399 mbx->size = IXGBE_VFMAILBOX_SIZE;
401 mbx->ops.read = ixgbe_read_mbx_vf;
402 mbx->ops.write = ixgbe_write_mbx_vf;
403 mbx->ops.read_posted = ixgbe_read_posted_mbx;
404 mbx->ops.write_posted = ixgbe_write_posted_mbx;
405 mbx->ops.check_for_msg = ixgbe_check_for_msg_vf;
406 mbx->ops.check_for_ack = ixgbe_check_for_ack_vf;
407 mbx->ops.check_for_rst = ixgbe_check_for_rst_vf;
409 mbx->stats.msgs_tx = 0;
410 mbx->stats.msgs_rx = 0;
416 static s32 ixgbe_check_for_bit_pf(struct ixgbe_hw *hw, u32 mask, s32 index)
418 u32 mbvficr = IXGBE_READ_REG(hw, IXGBE_MBVFICR(index));
419 s32 ret_val = IXGBE_ERR_MBX;
421 if (mbvficr & mask) {
422 ret_val = IXGBE_SUCCESS;
423 IXGBE_WRITE_REG(hw, IXGBE_MBVFICR(index), mask);
430 * ixgbe_check_for_msg_pf - checks to see if the VF has sent mail
431 * @hw: pointer to the HW structure
432 * @vf_number: the VF index
434 * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
436 static s32 ixgbe_check_for_msg_pf(struct ixgbe_hw *hw, u16 vf_number)
438 s32 ret_val = IXGBE_ERR_MBX;
439 s32 index = IXGBE_MBVFICR_INDEX(vf_number);
440 u32 vf_bit = vf_number % 16;
442 DEBUGFUNC("ixgbe_check_for_msg_pf");
444 if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFREQ_VF1 << vf_bit,
446 ret_val = IXGBE_SUCCESS;
447 hw->mbx.stats.reqs++;
454 * ixgbe_check_for_ack_pf - checks to see if the VF has ACKed
455 * @hw: pointer to the HW structure
456 * @vf_number: the VF index
458 * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
460 static s32 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_number)
462 s32 ret_val = IXGBE_ERR_MBX;
463 s32 index = IXGBE_MBVFICR_INDEX(vf_number);
464 u32 vf_bit = vf_number % 16;
466 DEBUGFUNC("ixgbe_check_for_ack_pf");
468 if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFACK_VF1 << vf_bit,
470 ret_val = IXGBE_SUCCESS;
471 hw->mbx.stats.acks++;
478 * ixgbe_check_for_rst_pf - checks to see if the VF has reset
479 * @hw: pointer to the HW structure
480 * @vf_number: the VF index
482 * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
484 static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_number)
486 u32 reg_offset = (vf_number < 32) ? 0 : 1;
487 u32 vf_shift = vf_number % 32;
489 s32 ret_val = IXGBE_ERR_MBX;
491 DEBUGFUNC("ixgbe_check_for_rst_pf");
493 switch (hw->mac.type) {
494 case ixgbe_mac_82599EB:
495 vflre = IXGBE_READ_REG(hw, IXGBE_VFLRE(reg_offset));
498 case ixgbe_mac_X550EM_x:
499 case ixgbe_mac_X550EM_a:
501 vflre = IXGBE_READ_REG(hw, IXGBE_VFLREC(reg_offset));
507 if (vflre & (1 << vf_shift)) {
508 ret_val = IXGBE_SUCCESS;
509 IXGBE_WRITE_REG(hw, IXGBE_VFLREC(reg_offset), (1 << vf_shift));
510 hw->mbx.stats.rsts++;
517 * ixgbe_obtain_mbx_lock_pf - obtain mailbox lock
518 * @hw: pointer to the HW structure
519 * @vf_number: the VF index
521 * return SUCCESS if we obtained the mailbox lock
523 static s32 ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_number)
525 s32 ret_val = IXGBE_ERR_MBX;
528 DEBUGFUNC("ixgbe_obtain_mbx_lock_pf");
530 /* Take ownership of the buffer */
531 IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_PFU);
533 /* reserve mailbox for vf use */
534 p2v_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_number));
535 if (p2v_mailbox & IXGBE_PFMAILBOX_PFU)
536 ret_val = IXGBE_SUCCESS;
538 ERROR_REPORT2(IXGBE_ERROR_POLLING,
539 "Failed to obtain mailbox lock for VF%d", vf_number);
546 * ixgbe_write_mbx_pf - Places a message in the mailbox
547 * @hw: pointer to the HW structure
548 * @msg: The message buffer
549 * @size: Length of buffer
550 * @vf_number: the VF index
552 * returns SUCCESS if it successfully copied message into the buffer
554 static s32 ixgbe_write_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
560 DEBUGFUNC("ixgbe_write_mbx_pf");
562 /* lock the mailbox to prevent pf/vf race condition */
563 ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number);
567 /* flush msg and acks as we are overwriting the message buffer */
568 ixgbe_check_for_msg_pf(hw, vf_number);
569 ixgbe_check_for_ack_pf(hw, vf_number);
571 /* copy the caller specified message to the mailbox memory buffer */
572 for (i = 0; i < size; i++)
573 IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i, msg[i]);
575 /* Interrupt VF to tell it a message has been sent and release buffer*/
576 IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_STS);
579 hw->mbx.stats.msgs_tx++;
587 * ixgbe_read_mbx_pf - Read a message from the mailbox
588 * @hw: pointer to the HW structure
589 * @msg: The message buffer
590 * @size: Length of buffer
591 * @vf_number: the VF index
593 * This function copies a message from the mailbox buffer to the caller's
594 * memory buffer. The presumption is that the caller knows that there was
595 * a message due to a VF request so no polling for message is needed.
597 static s32 ixgbe_read_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
603 DEBUGFUNC("ixgbe_read_mbx_pf");
605 /* lock the mailbox to prevent pf/vf race condition */
606 ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number);
610 /* copy the message to the mailbox memory buffer */
611 for (i = 0; i < size; i++)
612 msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i);
614 /* Acknowledge the message and release buffer */
615 IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_ACK);
618 hw->mbx.stats.msgs_rx++;
625 * ixv_init_mbx_params_pf - set initial values for pf mailbox
626 * @hw: pointer to the HW structure
628 * Initializes the hw->mbx struct to correct values for pf mailbox
630 void ixv_init_mbx_params_pf(struct ixgbe_hw *hw)
632 struct ixgbe_mbx_info *mbx = &hw->mbx;
634 if (hw->mac.type != ixgbe_mac_82599EB &&
635 hw->mac.type != ixgbe_mac_X550 &&
636 hw->mac.type != ixgbe_mac_X550EM_x &&
637 hw->mac.type != ixgbe_mac_X550EM_a &&
638 hw->mac.type != ixgbe_mac_X540)
644 mbx->size = IXGBE_VFMAILBOX_SIZE;
646 mbx->ops.read = ixgbe_read_mbx_pf;
647 mbx->ops.write = ixgbe_write_mbx_pf;
648 mbx->ops.read_posted = ixgbe_read_posted_mbx;
649 mbx->ops.write_posted = ixgbe_write_posted_mbx;
650 mbx->ops.check_for_msg = ixgbe_check_for_msg_pf;
651 mbx->ops.check_for_ack = ixgbe_check_for_ack_pf;
652 mbx->ops.check_for_rst = ixgbe_check_for_rst_pf;
654 mbx->stats.msgs_tx = 0;
655 mbx->stats.msgs_rx = 0;