xref: /freebsd/sys/dev/ixgbe/ixgbe_mbx.c (revision 09a53ad8f1318c5daae6cfb19d97f4f6459f0013)
1 /******************************************************************************
2 
3   Copyright (c) 2001-2015, Intel Corporation
4   All rights reserved.
5 
6   Redistribution and use in source and binary forms, with or without
7   modification, are permitted provided that the following conditions are met:
8 
9    1. Redistributions of source code must retain the above copyright notice,
10       this list of conditions and the following disclaimer.
11 
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.
15 
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.
19 
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.
31 
32 ******************************************************************************/
33 /*$FreeBSD$*/
34 
35 #include "ixgbe_type.h"
36 #include "ixgbe_mbx.h"
37 
38 /**
39  *  ixgbe_read_mbx - Reads a message from the mailbox
40  *  @hw: pointer to the HW structure
41  *  @msg: The message buffer
42  *  @size: Length of buffer
43  *  @mbx_id: id of mailbox to read
44  *
45  *  returns SUCCESS if it successfully read message from buffer
46  **/
47 s32 ixgbe_read_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
48 {
49 	struct ixgbe_mbx_info *mbx = &hw->mbx;
50 	s32 ret_val = IXGBE_ERR_MBX;
51 
52 	DEBUGFUNC("ixgbe_read_mbx");
53 
54 	/* limit read to size of mailbox */
55 	if (size > mbx->size)
56 		size = mbx->size;
57 
58 	if (mbx->ops.read)
59 		ret_val = mbx->ops.read(hw, msg, size, mbx_id);
60 
61 	return ret_val;
62 }
63 
64 /**
65  *  ixgbe_write_mbx - Write a message to the mailbox
66  *  @hw: pointer to the HW structure
67  *  @msg: The message buffer
68  *  @size: Length of buffer
69  *  @mbx_id: id of mailbox to write
70  *
71  *  returns SUCCESS if it successfully copied message into the buffer
72  **/
73 s32 ixgbe_write_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
74 {
75 	struct ixgbe_mbx_info *mbx = &hw->mbx;
76 	s32 ret_val = IXGBE_SUCCESS;
77 
78 	DEBUGFUNC("ixgbe_write_mbx");
79 
80 	if (size > mbx->size) {
81 		ret_val = IXGBE_ERR_MBX;
82 		ERROR_REPORT2(IXGBE_ERROR_ARGUMENT,
83 			     "Invalid mailbox message size %d", size);
84 	} else if (mbx->ops.write)
85 		ret_val = mbx->ops.write(hw, msg, size, mbx_id);
86 
87 	return ret_val;
88 }
89 
90 /**
91  *  ixgbe_check_for_msg - checks to see if someone sent us mail
92  *  @hw: pointer to the HW structure
93  *  @mbx_id: id of mailbox to check
94  *
95  *  returns SUCCESS if the Status bit was found or else ERR_MBX
96  **/
97 s32 ixgbe_check_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
98 {
99 	struct ixgbe_mbx_info *mbx = &hw->mbx;
100 	s32 ret_val = IXGBE_ERR_MBX;
101 
102 	DEBUGFUNC("ixgbe_check_for_msg");
103 
104 	if (mbx->ops.check_for_msg)
105 		ret_val = mbx->ops.check_for_msg(hw, mbx_id);
106 
107 	return ret_val;
108 }
109 
110 /**
111  *  ixgbe_check_for_ack - checks to see if someone sent us ACK
112  *  @hw: pointer to the HW structure
113  *  @mbx_id: id of mailbox to check
114  *
115  *  returns SUCCESS if the Status bit was found or else ERR_MBX
116  **/
117 s32 ixgbe_check_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
118 {
119 	struct ixgbe_mbx_info *mbx = &hw->mbx;
120 	s32 ret_val = IXGBE_ERR_MBX;
121 
122 	DEBUGFUNC("ixgbe_check_for_ack");
123 
124 	if (mbx->ops.check_for_ack)
125 		ret_val = mbx->ops.check_for_ack(hw, mbx_id);
126 
127 	return ret_val;
128 }
129 
130 /**
131  *  ixgbe_check_for_rst - checks to see if other side has reset
132  *  @hw: pointer to the HW structure
133  *  @mbx_id: id of mailbox to check
134  *
135  *  returns SUCCESS if the Status bit was found or else ERR_MBX
136  **/
137 s32 ixgbe_check_for_rst(struct ixgbe_hw *hw, u16 mbx_id)
138 {
139 	struct ixgbe_mbx_info *mbx = &hw->mbx;
140 	s32 ret_val = IXGBE_ERR_MBX;
141 
142 	DEBUGFUNC("ixgbe_check_for_rst");
143 
144 	if (mbx->ops.check_for_rst)
145 		ret_val = mbx->ops.check_for_rst(hw, mbx_id);
146 
147 	return ret_val;
148 }
149 
150 /**
151  *  ixgbe_poll_for_msg - Wait for message notification
152  *  @hw: pointer to the HW structure
153  *  @mbx_id: id of mailbox to write
154  *
155  *  returns SUCCESS if it successfully received a message notification
156  **/
157 static s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
158 {
159 	struct ixgbe_mbx_info *mbx = &hw->mbx;
160 	int countdown = mbx->timeout;
161 
162 	DEBUGFUNC("ixgbe_poll_for_msg");
163 
164 	if (!countdown || !mbx->ops.check_for_msg)
165 		goto out;
166 
167 	while (countdown && mbx->ops.check_for_msg(hw, mbx_id)) {
168 		countdown--;
169 		if (!countdown)
170 			break;
171 		usec_delay(mbx->usec_delay);
172 	}
173 
174 	if (countdown == 0)
175 		ERROR_REPORT2(IXGBE_ERROR_POLLING,
176 			   "Polling for VF%d mailbox message timedout", mbx_id);
177 
178 out:
179 	return countdown ? IXGBE_SUCCESS : IXGBE_ERR_MBX;
180 }
181 
182 /**
183  *  ixgbe_poll_for_ack - Wait for message acknowledgement
184  *  @hw: pointer to the HW structure
185  *  @mbx_id: id of mailbox to write
186  *
187  *  returns SUCCESS if it successfully received a message acknowledgement
188  **/
189 static s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
190 {
191 	struct ixgbe_mbx_info *mbx = &hw->mbx;
192 	int countdown = mbx->timeout;
193 
194 	DEBUGFUNC("ixgbe_poll_for_ack");
195 
196 	if (!countdown || !mbx->ops.check_for_ack)
197 		goto out;
198 
199 	while (countdown && mbx->ops.check_for_ack(hw, mbx_id)) {
200 		countdown--;
201 		if (!countdown)
202 			break;
203 		usec_delay(mbx->usec_delay);
204 	}
205 
206 	if (countdown == 0)
207 		ERROR_REPORT2(IXGBE_ERROR_POLLING,
208 			     "Polling for VF%d mailbox ack timedout", mbx_id);
209 
210 out:
211 	return countdown ? IXGBE_SUCCESS : IXGBE_ERR_MBX;
212 }
213 
214 /**
215  *  ixgbe_read_posted_mbx - Wait for message notification and receive message
216  *  @hw: pointer to the HW structure
217  *  @msg: The message buffer
218  *  @size: Length of buffer
219  *  @mbx_id: id of mailbox to write
220  *
221  *  returns SUCCESS if it successfully received a message notification and
222  *  copied it into the receive buffer.
223  **/
224 s32 ixgbe_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
225 {
226 	struct ixgbe_mbx_info *mbx = &hw->mbx;
227 	s32 ret_val = IXGBE_ERR_MBX;
228 
229 	DEBUGFUNC("ixgbe_read_posted_mbx");
230 
231 	if (!mbx->ops.read)
232 		goto out;
233 
234 	ret_val = ixgbe_poll_for_msg(hw, mbx_id);
235 
236 	/* if ack received read message, otherwise we timed out */
237 	if (!ret_val)
238 		ret_val = mbx->ops.read(hw, msg, size, mbx_id);
239 out:
240 	return ret_val;
241 }
242 
243 /**
244  *  ixgbe_write_posted_mbx - Write a message to the mailbox, wait for ack
245  *  @hw: pointer to the HW structure
246  *  @msg: The message buffer
247  *  @size: Length of buffer
248  *  @mbx_id: id of mailbox to write
249  *
250  *  returns SUCCESS if it successfully copied message into the buffer and
251  *  received an ack to that message within delay * timeout period
252  **/
253 s32 ixgbe_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size,
254 			   u16 mbx_id)
255 {
256 	struct ixgbe_mbx_info *mbx = &hw->mbx;
257 	s32 ret_val = IXGBE_ERR_MBX;
258 
259 	DEBUGFUNC("ixgbe_write_posted_mbx");
260 
261 	/* exit if either we can't write or there isn't a defined timeout */
262 	if (!mbx->ops.write || !mbx->timeout)
263 		goto out;
264 
265 	/* send msg */
266 	ret_val = mbx->ops.write(hw, msg, size, mbx_id);
267 
268 	/* if msg sent wait until we receive an ack */
269 	if (!ret_val)
270 		ret_val = ixgbe_poll_for_ack(hw, mbx_id);
271 out:
272 	return ret_val;
273 }
274 
275 /**
276  *  ixgbe_init_mbx_ops_generic - Initialize MB function pointers
277  *  @hw: pointer to the HW structure
278  *
279  *  Setups up the mailbox read and write message function pointers
280  **/
281 void ixgbe_init_mbx_ops_generic(struct ixgbe_hw *hw)
282 {
283 	struct ixgbe_mbx_info *mbx = &hw->mbx;
284 
285 	mbx->ops.read_posted = ixgbe_read_posted_mbx;
286 	mbx->ops.write_posted = ixgbe_write_posted_mbx;
287 }
288 
289 /**
290  *  ixgbe_read_v2p_mailbox - read v2p mailbox
291  *  @hw: pointer to the HW structure
292  *
293  *  This function is used to read the v2p mailbox without losing the read to
294  *  clear status bits.
295  **/
296 static u32 ixgbe_read_v2p_mailbox(struct ixgbe_hw *hw)
297 {
298 	u32 v2p_mailbox = IXGBE_READ_REG(hw, IXGBE_VFMAILBOX);
299 
300 	v2p_mailbox |= hw->mbx.v2p_mailbox;
301 	hw->mbx.v2p_mailbox |= v2p_mailbox & IXGBE_VFMAILBOX_R2C_BITS;
302 
303 	return v2p_mailbox;
304 }
305 
306 /**
307  *  ixgbe_check_for_bit_vf - Determine if a status bit was set
308  *  @hw: pointer to the HW structure
309  *  @mask: bitmask for bits to be tested and cleared
310  *
311  *  This function is used to check for the read to clear bits within
312  *  the V2P mailbox.
313  **/
314 static s32 ixgbe_check_for_bit_vf(struct ixgbe_hw *hw, u32 mask)
315 {
316 	u32 v2p_mailbox = ixgbe_read_v2p_mailbox(hw);
317 	s32 ret_val = IXGBE_ERR_MBX;
318 
319 	if (v2p_mailbox & mask)
320 		ret_val = IXGBE_SUCCESS;
321 
322 	hw->mbx.v2p_mailbox &= ~mask;
323 
324 	return ret_val;
325 }
326 
327 /**
328  *  ixgbe_check_for_msg_vf - checks to see if the PF has sent mail
329  *  @hw: pointer to the HW structure
330  *  @mbx_id: id of mailbox to check
331  *
332  *  returns SUCCESS if the PF has set the Status bit or else ERR_MBX
333  **/
334 static s32 ixgbe_check_for_msg_vf(struct ixgbe_hw *hw, u16 mbx_id)
335 {
336 	s32 ret_val = IXGBE_ERR_MBX;
337 
338 	UNREFERENCED_1PARAMETER(mbx_id);
339 	DEBUGFUNC("ixgbe_check_for_msg_vf");
340 
341 	if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFSTS)) {
342 		ret_val = IXGBE_SUCCESS;
343 		hw->mbx.stats.reqs++;
344 	}
345 
346 	return ret_val;
347 }
348 
349 /**
350  *  ixgbe_check_for_ack_vf - checks to see if the PF has ACK'd
351  *  @hw: pointer to the HW structure
352  *  @mbx_id: id of mailbox to check
353  *
354  *  returns SUCCESS if the PF has set the ACK bit or else ERR_MBX
355  **/
356 static s32 ixgbe_check_for_ack_vf(struct ixgbe_hw *hw, u16 mbx_id)
357 {
358 	s32 ret_val = IXGBE_ERR_MBX;
359 
360 	UNREFERENCED_1PARAMETER(mbx_id);
361 	DEBUGFUNC("ixgbe_check_for_ack_vf");
362 
363 	if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFACK)) {
364 		ret_val = IXGBE_SUCCESS;
365 		hw->mbx.stats.acks++;
366 	}
367 
368 	return ret_val;
369 }
370 
371 /**
372  *  ixgbe_check_for_rst_vf - checks to see if the PF has reset
373  *  @hw: pointer to the HW structure
374  *  @mbx_id: id of mailbox to check
375  *
376  *  returns TRUE if the PF has set the reset done bit or else FALSE
377  **/
378 static s32 ixgbe_check_for_rst_vf(struct ixgbe_hw *hw, u16 mbx_id)
379 {
380 	s32 ret_val = IXGBE_ERR_MBX;
381 
382 	UNREFERENCED_1PARAMETER(mbx_id);
383 	DEBUGFUNC("ixgbe_check_for_rst_vf");
384 
385 	if (!ixgbe_check_for_bit_vf(hw, (IXGBE_VFMAILBOX_RSTD |
386 	    IXGBE_VFMAILBOX_RSTI))) {
387 		ret_val = IXGBE_SUCCESS;
388 		hw->mbx.stats.rsts++;
389 	}
390 
391 	return ret_val;
392 }
393 
394 /**
395  *  ixgbe_obtain_mbx_lock_vf - obtain mailbox lock
396  *  @hw: pointer to the HW structure
397  *
398  *  return SUCCESS if we obtained the mailbox lock
399  **/
400 static s32 ixgbe_obtain_mbx_lock_vf(struct ixgbe_hw *hw)
401 {
402 	s32 ret_val = IXGBE_ERR_MBX;
403 
404 	DEBUGFUNC("ixgbe_obtain_mbx_lock_vf");
405 
406 	/* Take ownership of the buffer */
407 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_VFU);
408 
409 	/* reserve mailbox for vf use */
410 	if (ixgbe_read_v2p_mailbox(hw) & IXGBE_VFMAILBOX_VFU)
411 		ret_val = IXGBE_SUCCESS;
412 
413 	return ret_val;
414 }
415 
416 /**
417  *  ixgbe_write_mbx_vf - Write a message to the mailbox
418  *  @hw: pointer to the HW structure
419  *  @msg: The message buffer
420  *  @size: Length of buffer
421  *  @mbx_id: id of mailbox to write
422  *
423  *  returns SUCCESS if it successfully copied message into the buffer
424  **/
425 static s32 ixgbe_write_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,
426 			      u16 mbx_id)
427 {
428 	s32 ret_val;
429 	u16 i;
430 
431 	UNREFERENCED_1PARAMETER(mbx_id);
432 
433 	DEBUGFUNC("ixgbe_write_mbx_vf");
434 
435 	/* lock the mailbox to prevent pf/vf race condition */
436 	ret_val = ixgbe_obtain_mbx_lock_vf(hw);
437 	if (ret_val)
438 		goto out_no_write;
439 
440 	/* flush msg and acks as we are overwriting the message buffer */
441 	ixgbe_check_for_msg_vf(hw, 0);
442 	ixgbe_check_for_ack_vf(hw, 0);
443 
444 	/* copy the caller specified message to the mailbox memory buffer */
445 	for (i = 0; i < size; i++)
446 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFMBMEM, i, msg[i]);
447 
448 	/* update stats */
449 	hw->mbx.stats.msgs_tx++;
450 
451 	/* Drop VFU and interrupt the PF to tell it a message has been sent */
452 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_REQ);
453 
454 out_no_write:
455 	return ret_val;
456 }
457 
458 /**
459  *  ixgbe_read_mbx_vf - Reads a message from the inbox intended for vf
460  *  @hw: pointer to the HW structure
461  *  @msg: The message buffer
462  *  @size: Length of buffer
463  *  @mbx_id: id of mailbox to read
464  *
465  *  returns SUCCESS if it successfully read message from buffer
466  **/
467 static s32 ixgbe_read_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,
468 			     u16 mbx_id)
469 {
470 	s32 ret_val = IXGBE_SUCCESS;
471 	u16 i;
472 
473 	DEBUGFUNC("ixgbe_read_mbx_vf");
474 	UNREFERENCED_1PARAMETER(mbx_id);
475 
476 	/* lock the mailbox to prevent pf/vf race condition */
477 	ret_val = ixgbe_obtain_mbx_lock_vf(hw);
478 	if (ret_val)
479 		goto out_no_read;
480 
481 	/* copy the message from the mailbox memory buffer */
482 	for (i = 0; i < size; i++)
483 		msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i);
484 
485 	/* Acknowledge receipt and release mailbox, then we're done */
486 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_ACK);
487 
488 	/* update stats */
489 	hw->mbx.stats.msgs_rx++;
490 
491 out_no_read:
492 	return ret_val;
493 }
494 
495 /**
496  *  ixgbe_init_mbx_params_vf - set initial values for vf mailbox
497  *  @hw: pointer to the HW structure
498  *
499  *  Initializes the hw->mbx struct to correct values for vf mailbox
500  */
501 void ixgbe_init_mbx_params_vf(struct ixgbe_hw *hw)
502 {
503 	struct ixgbe_mbx_info *mbx = &hw->mbx;
504 
505 	/* start mailbox as timed out and let the reset_hw call set the timeout
506 	 * value to begin communications */
507 	mbx->timeout = 0;
508 	mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;
509 
510 	mbx->size = IXGBE_VFMAILBOX_SIZE;
511 
512 	mbx->ops.read = ixgbe_read_mbx_vf;
513 	mbx->ops.write = ixgbe_write_mbx_vf;
514 	mbx->ops.read_posted = ixgbe_read_posted_mbx;
515 	mbx->ops.write_posted = ixgbe_write_posted_mbx;
516 	mbx->ops.check_for_msg = ixgbe_check_for_msg_vf;
517 	mbx->ops.check_for_ack = ixgbe_check_for_ack_vf;
518 	mbx->ops.check_for_rst = ixgbe_check_for_rst_vf;
519 
520 	mbx->stats.msgs_tx = 0;
521 	mbx->stats.msgs_rx = 0;
522 	mbx->stats.reqs = 0;
523 	mbx->stats.acks = 0;
524 	mbx->stats.rsts = 0;
525 }
526 
527 static s32 ixgbe_check_for_bit_pf(struct ixgbe_hw *hw, u32 mask, s32 index)
528 {
529 	u32 mbvficr = IXGBE_READ_REG(hw, IXGBE_MBVFICR(index));
530 	s32 ret_val = IXGBE_ERR_MBX;
531 
532 	if (mbvficr & mask) {
533 		ret_val = IXGBE_SUCCESS;
534 		IXGBE_WRITE_REG(hw, IXGBE_MBVFICR(index), mask);
535 	}
536 
537 	return ret_val;
538 }
539 
540 /**
541  *  ixgbe_check_for_msg_pf - checks to see if the VF has sent mail
542  *  @hw: pointer to the HW structure
543  *  @vf_number: the VF index
544  *
545  *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
546  **/
547 static s32 ixgbe_check_for_msg_pf(struct ixgbe_hw *hw, u16 vf_number)
548 {
549 	s32 ret_val = IXGBE_ERR_MBX;
550 	s32 index = IXGBE_MBVFICR_INDEX(vf_number);
551 	u32 vf_bit = vf_number % 16;
552 
553 	DEBUGFUNC("ixgbe_check_for_msg_pf");
554 
555 	if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFREQ_VF1 << vf_bit,
556 				    index)) {
557 		ret_val = IXGBE_SUCCESS;
558 		hw->mbx.stats.reqs++;
559 	}
560 
561 	return ret_val;
562 }
563 
564 /**
565  *  ixgbe_check_for_ack_pf - checks to see if the VF has ACKed
566  *  @hw: pointer to the HW structure
567  *  @vf_number: the VF index
568  *
569  *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
570  **/
571 static s32 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_number)
572 {
573 	s32 ret_val = IXGBE_ERR_MBX;
574 	s32 index = IXGBE_MBVFICR_INDEX(vf_number);
575 	u32 vf_bit = vf_number % 16;
576 
577 	DEBUGFUNC("ixgbe_check_for_ack_pf");
578 
579 	if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFACK_VF1 << vf_bit,
580 				    index)) {
581 		ret_val = IXGBE_SUCCESS;
582 		hw->mbx.stats.acks++;
583 	}
584 
585 	return ret_val;
586 }
587 
588 /**
589  *  ixgbe_check_for_rst_pf - checks to see if the VF has reset
590  *  @hw: pointer to the HW structure
591  *  @vf_number: the VF index
592  *
593  *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
594  **/
595 static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_number)
596 {
597 	u32 reg_offset = (vf_number < 32) ? 0 : 1;
598 	u32 vf_shift = vf_number % 32;
599 	u32 vflre = 0;
600 	s32 ret_val = IXGBE_ERR_MBX;
601 
602 	DEBUGFUNC("ixgbe_check_for_rst_pf");
603 
604 	switch (hw->mac.type) {
605 	case ixgbe_mac_82599EB:
606 		vflre = IXGBE_READ_REG(hw, IXGBE_VFLRE(reg_offset));
607 		break;
608 	case ixgbe_mac_X550:
609 	case ixgbe_mac_X550EM_x:
610 	case ixgbe_mac_X540:
611 		vflre = IXGBE_READ_REG(hw, IXGBE_VFLREC(reg_offset));
612 		break;
613 	default:
614 		break;
615 	}
616 
617 	if (vflre & (1 << vf_shift)) {
618 		ret_val = IXGBE_SUCCESS;
619 		IXGBE_WRITE_REG(hw, IXGBE_VFLREC(reg_offset), (1 << vf_shift));
620 		hw->mbx.stats.rsts++;
621 	}
622 
623 	return ret_val;
624 }
625 
626 /**
627  *  ixgbe_obtain_mbx_lock_pf - obtain mailbox lock
628  *  @hw: pointer to the HW structure
629  *  @vf_number: the VF index
630  *
631  *  return SUCCESS if we obtained the mailbox lock
632  **/
633 static s32 ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_number)
634 {
635 	s32 ret_val = IXGBE_ERR_MBX;
636 	u32 p2v_mailbox;
637 
638 	DEBUGFUNC("ixgbe_obtain_mbx_lock_pf");
639 
640 	/* Take ownership of the buffer */
641 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_PFU);
642 
643 	/* reserve mailbox for vf use */
644 	p2v_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_number));
645 	if (p2v_mailbox & IXGBE_PFMAILBOX_PFU)
646 		ret_val = IXGBE_SUCCESS;
647 	else
648 		ERROR_REPORT2(IXGBE_ERROR_POLLING,
649 			   "Failed to obtain mailbox lock for VF%d", vf_number);
650 
651 
652 	return ret_val;
653 }
654 
655 /**
656  *  ixgbe_write_mbx_pf - Places a message in the mailbox
657  *  @hw: pointer to the HW structure
658  *  @msg: The message buffer
659  *  @size: Length of buffer
660  *  @vf_number: the VF index
661  *
662  *  returns SUCCESS if it successfully copied message into the buffer
663  **/
664 static s32 ixgbe_write_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
665 			      u16 vf_number)
666 {
667 	s32 ret_val;
668 	u16 i;
669 
670 	DEBUGFUNC("ixgbe_write_mbx_pf");
671 
672 	/* lock the mailbox to prevent pf/vf race condition */
673 	ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number);
674 	if (ret_val)
675 		goto out_no_write;
676 
677 	/* flush msg and acks as we are overwriting the message buffer */
678 	ixgbe_check_for_msg_pf(hw, vf_number);
679 	ixgbe_check_for_ack_pf(hw, vf_number);
680 
681 	/* copy the caller specified message to the mailbox memory buffer */
682 	for (i = 0; i < size; i++)
683 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i, msg[i]);
684 
685 	/* Interrupt VF to tell it a message has been sent and release buffer*/
686 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_STS);
687 
688 	/* update stats */
689 	hw->mbx.stats.msgs_tx++;
690 
691 out_no_write:
692 	return ret_val;
693 
694 }
695 
696 /**
697  *  ixgbe_read_mbx_pf - Read a message from the mailbox
698  *  @hw: pointer to the HW structure
699  *  @msg: The message buffer
700  *  @size: Length of buffer
701  *  @vf_number: the VF index
702  *
703  *  This function copies a message from the mailbox buffer to the caller's
704  *  memory buffer.  The presumption is that the caller knows that there was
705  *  a message due to a VF request so no polling for message is needed.
706  **/
707 static s32 ixgbe_read_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
708 			     u16 vf_number)
709 {
710 	s32 ret_val;
711 	u16 i;
712 
713 	DEBUGFUNC("ixgbe_read_mbx_pf");
714 
715 	/* lock the mailbox to prevent pf/vf race condition */
716 	ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number);
717 	if (ret_val)
718 		goto out_no_read;
719 
720 	/* copy the message to the mailbox memory buffer */
721 	for (i = 0; i < size; i++)
722 		msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i);
723 
724 	/* Acknowledge the message and release buffer */
725 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_ACK);
726 
727 	/* update stats */
728 	hw->mbx.stats.msgs_rx++;
729 
730 out_no_read:
731 	return ret_val;
732 }
733 
734 /**
735  *  ixgbe_init_mbx_params_pf - set initial values for pf mailbox
736  *  @hw: pointer to the HW structure
737  *
738  *  Initializes the hw->mbx struct to correct values for pf mailbox
739  */
740 void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw)
741 {
742 	struct ixgbe_mbx_info *mbx = &hw->mbx;
743 
744 	if (hw->mac.type != ixgbe_mac_82599EB &&
745 	    hw->mac.type != ixgbe_mac_X550 &&
746 	    hw->mac.type != ixgbe_mac_X550EM_x &&
747 	    hw->mac.type != ixgbe_mac_X540)
748 		return;
749 
750 	mbx->timeout = 0;
751 	mbx->usec_delay = 0;
752 
753 	mbx->size = IXGBE_VFMAILBOX_SIZE;
754 
755 	mbx->ops.read = ixgbe_read_mbx_pf;
756 	mbx->ops.write = ixgbe_write_mbx_pf;
757 	mbx->ops.read_posted = ixgbe_read_posted_mbx;
758 	mbx->ops.write_posted = ixgbe_write_posted_mbx;
759 	mbx->ops.check_for_msg = ixgbe_check_for_msg_pf;
760 	mbx->ops.check_for_ack = ixgbe_check_for_ack_pf;
761 	mbx->ops.check_for_rst = ixgbe_check_for_rst_pf;
762 
763 	mbx->stats.msgs_tx = 0;
764 	mbx->stats.msgs_rx = 0;
765 	mbx->stats.reqs = 0;
766 	mbx->stats.acks = 0;
767 	mbx->stats.rsts = 0;
768 }
769