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