xref: /freebsd/sys/dev/ixgbe/ixgbe_mbx.c (revision aa0a1e58)
1 /******************************************************************************
2 
3   Copyright (c) 2001-2010, 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_PARAMETER(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_PARAMETER(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_PARAMETER(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_PARAMETER(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_PARAMETER(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 	default:
600 		goto out;
601 		break;
602 	}
603 
604 	if (vflre & (1 << vf_shift)) {
605 		ret_val = IXGBE_SUCCESS;
606 		IXGBE_WRITE_REG(hw, IXGBE_VFLREC(reg_offset), (1 << vf_shift));
607 		hw->mbx.stats.rsts++;
608 	}
609 
610 out:
611 	return ret_val;
612 }
613 
614 /**
615  *  ixgbe_obtain_mbx_lock_pf - obtain mailbox lock
616  *  @hw: pointer to the HW structure
617  *  @vf_number: the VF index
618  *
619  *  return SUCCESS if we obtained the mailbox lock
620  **/
621 static s32 ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_number)
622 {
623 	s32 ret_val = IXGBE_ERR_MBX;
624 	u32 p2v_mailbox;
625 
626 	DEBUGFUNC("ixgbe_obtain_mbx_lock_pf");
627 
628 	/* Take ownership of the buffer */
629 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_PFU);
630 
631 	/* reserve mailbox for vf use */
632 	p2v_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_number));
633 	if (p2v_mailbox & IXGBE_PFMAILBOX_PFU)
634 		ret_val = IXGBE_SUCCESS;
635 
636 	return ret_val;
637 }
638 
639 /**
640  *  ixgbe_write_mbx_pf - Places a message in the mailbox
641  *  @hw: pointer to the HW structure
642  *  @msg: The message buffer
643  *  @size: Length of buffer
644  *  @vf_number: the VF index
645  *
646  *  returns SUCCESS if it successfully copied message into the buffer
647  **/
648 static s32 ixgbe_write_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
649                               u16 vf_number)
650 {
651 	s32 ret_val;
652 	u16 i;
653 
654 	DEBUGFUNC("ixgbe_write_mbx_pf");
655 
656 	/* lock the mailbox to prevent pf/vf race condition */
657 	ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number);
658 	if (ret_val)
659 		goto out_no_write;
660 
661 	/* flush msg and acks as we are overwriting the message buffer */
662 	ixgbe_check_for_msg_pf(hw, vf_number);
663 	ixgbe_check_for_ack_pf(hw, vf_number);
664 
665 	/* copy the caller specified message to the mailbox memory buffer */
666 	for (i = 0; i < size; i++)
667 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i, msg[i]);
668 
669 	/* Interrupt VF to tell it a message has been sent and release buffer*/
670 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_STS);
671 
672 	/* update stats */
673 	hw->mbx.stats.msgs_tx++;
674 
675 out_no_write:
676 	return ret_val;
677 
678 }
679 
680 /**
681  *  ixgbe_read_mbx_pf - Read a message from the mailbox
682  *  @hw: pointer to the HW structure
683  *  @msg: The message buffer
684  *  @size: Length of buffer
685  *  @vf_number: the VF index
686  *
687  *  This function copies a message from the mailbox buffer to the caller's
688  *  memory buffer.  The presumption is that the caller knows that there was
689  *  a message due to a VF request so no polling for message is needed.
690  **/
691 static s32 ixgbe_read_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
692                              u16 vf_number)
693 {
694 	s32 ret_val;
695 	u16 i;
696 
697 	DEBUGFUNC("ixgbe_read_mbx_pf");
698 
699 	/* lock the mailbox to prevent pf/vf race condition */
700 	ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number);
701 	if (ret_val)
702 		goto out_no_read;
703 
704 	/* copy the message to the mailbox memory buffer */
705 	for (i = 0; i < size; i++)
706 		msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i);
707 
708 	/* Acknowledge the message and release buffer */
709 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_ACK);
710 
711 	/* update stats */
712 	hw->mbx.stats.msgs_rx++;
713 
714 out_no_read:
715 	return ret_val;
716 }
717 
718 /**
719  *  ixgbe_init_mbx_params_pf - set initial values for pf mailbox
720  *  @hw: pointer to the HW structure
721  *
722  *  Initializes the hw->mbx struct to correct values for pf mailbox
723  */
724 void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw)
725 {
726 	struct ixgbe_mbx_info *mbx = &hw->mbx;
727 
728 	if (hw->mac.type != ixgbe_mac_82599EB)
729 		return;
730 
731 	mbx->timeout = 0;
732 	mbx->usec_delay = 0;
733 
734 	mbx->size = IXGBE_VFMAILBOX_SIZE;
735 
736 	mbx->ops.read = ixgbe_read_mbx_pf;
737 	mbx->ops.write = ixgbe_write_mbx_pf;
738 	mbx->ops.read_posted = ixgbe_read_posted_mbx;
739 	mbx->ops.write_posted = ixgbe_write_posted_mbx;
740 	mbx->ops.check_for_msg = ixgbe_check_for_msg_pf;
741 	mbx->ops.check_for_ack = ixgbe_check_for_ack_pf;
742 	mbx->ops.check_for_rst = ixgbe_check_for_rst_pf;
743 
744 	mbx->stats.msgs_tx = 0;
745 	mbx->stats.msgs_rx = 0;
746 	mbx->stats.reqs = 0;
747 	mbx->stats.acks = 0;
748 	mbx->stats.rsts = 0;
749 }
750 
751