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