1/******************************************************************************
2  SPDX-License-Identifier: BSD-3-Clause
3
4  Copyright (c) 2001-2020, Intel Corporation
5  All rights reserved.
6
7  Redistribution and use in source and binary forms, with or without
8  modification, are permitted provided that the following conditions are met:
9
10   1. Redistributions of source code must retain the above copyright notice,
11      this list of conditions and the following disclaimer.
12
13   2. Redistributions in binary form must reproduce the above copyright
14      notice, this list of conditions and the following disclaimer in the
15      documentation and/or other materials provided with the distribution.
16
17   3. Neither the name of the Intel Corporation nor the names of its
18      contributors may be used to endorse or promote products derived from
19      this software without specific prior written permission.
20
21  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  POSSIBILITY OF SUCH DAMAGE.
32
33******************************************************************************/
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 **/
47s32 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 **/
73s32 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 **/
97s32 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 **/
117s32 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 **/
137s32 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 **/
157static 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
178out:
179	return countdown ? IXGBE_SUCCESS : IXGBE_ERR_MBX;
180}
181
182/**
183 * ixgbe_poll_for_ack - Wait for message acknowledgment
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 acknowledgment
188 **/
189static 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
210out:
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 **/
224s32 ixgbe_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size,
225				 u16 mbx_id)
226{
227	struct ixgbe_mbx_info *mbx = &hw->mbx;
228	s32 ret_val = IXGBE_ERR_MBX;
229
230	DEBUGFUNC("ixgbe_read_posted_mbx");
231
232	if (!mbx->ops.read)
233		goto out;
234
235	ret_val = ixgbe_poll_for_msg(hw, mbx_id);
236
237	/* if ack received read message, otherwise we timed out */
238	if (!ret_val)
239		ret_val = mbx->ops.read(hw, msg, size, mbx_id);
240out:
241	return ret_val;
242}
243
244/**
245 * ixgbe_write_posted_mbx - Write a message to the mailbox, wait for ack
246 * @hw: pointer to the HW structure
247 * @msg: The message buffer
248 * @size: Length of buffer
249 * @mbx_id: id of mailbox to write
250 *
251 * returns SUCCESS if it successfully copied message into the buffer and
252 * received an ack to that message within delay * timeout period
253 **/
254s32 ixgbe_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size,
255				  u16 mbx_id)
256{
257	struct ixgbe_mbx_info *mbx = &hw->mbx;
258	s32 ret_val = IXGBE_ERR_MBX;
259
260	DEBUGFUNC("ixgbe_write_posted_mbx");
261
262	/* exit if either we can't write or there isn't a defined timeout */
263	if (!mbx->ops.write || !mbx->timeout)
264		goto out;
265
266	/* send msg */
267	ret_val = mbx->ops.write(hw, msg, size, mbx_id);
268
269	/* if msg sent wait until we receive an ack */
270	if (!ret_val)
271		ret_val = ixgbe_poll_for_ack(hw, mbx_id);
272out:
273	return ret_val;
274}
275
276/**
277 * ixgbe_init_mbx_ops_generic - Initialize MB function pointers
278 * @hw: pointer to the HW structure
279 *
280 * Setups up the mailbox read and write message function pointers
281 **/
282void ixgbe_init_mbx_ops_generic(struct ixgbe_hw *hw)
283{
284	struct ixgbe_mbx_info *mbx = &hw->mbx;
285
286	mbx->ops.read_posted = ixgbe_read_posted_mbx;
287	mbx->ops.write_posted = ixgbe_write_posted_mbx;
288}
289
290/**
291 * ixgbe_read_v2p_mailbox - read v2p mailbox
292 * @hw: pointer to the HW structure
293 *
294 * This function is used to read the v2p mailbox without losing the read to
295 * clear status bits.
296 **/
297static u32 ixgbe_read_v2p_mailbox(struct ixgbe_hw *hw)
298{
299	u32 v2p_mailbox = IXGBE_READ_REG(hw, IXGBE_VFMAILBOX);
300
301	v2p_mailbox |= hw->mbx.v2p_mailbox;
302	hw->mbx.v2p_mailbox |= v2p_mailbox & IXGBE_VFMAILBOX_R2C_BITS;
303
304	return v2p_mailbox;
305}
306
307/**
308 * ixgbe_check_for_bit_vf - Determine if a status bit was set
309 * @hw: pointer to the HW structure
310 * @mask: bitmask for bits to be tested and cleared
311 *
312 * This function is used to check for the read to clear bits within
313 * the V2P mailbox.
314 **/
315static s32 ixgbe_check_for_bit_vf(struct ixgbe_hw *hw, u32 mask)
316{
317	u32 v2p_mailbox = ixgbe_read_v2p_mailbox(hw);
318	s32 ret_val = IXGBE_ERR_MBX;
319
320	if (v2p_mailbox & mask)
321		ret_val = IXGBE_SUCCESS;
322
323	hw->mbx.v2p_mailbox &= ~mask;
324
325	return ret_val;
326}
327
328/**
329 * ixgbe_check_for_msg_vf - checks to see if the PF has sent mail
330 * @hw: pointer to the HW structure
331 * @mbx_id: id of mailbox to check
332 *
333 * returns SUCCESS if the PF has set the Status bit or else ERR_MBX
334 **/
335static s32 ixgbe_check_for_msg_vf(struct ixgbe_hw *hw, u16 mbx_id)
336{
337	s32 ret_val = IXGBE_ERR_MBX;
338
339	UNREFERENCED_1PARAMETER(mbx_id);
340	DEBUGFUNC("ixgbe_check_for_msg_vf");
341
342	if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFSTS)) {
343		ret_val = IXGBE_SUCCESS;
344		hw->mbx.stats.reqs++;
345	}
346
347	return ret_val;
348}
349
350/**
351 * ixgbe_check_for_ack_vf - checks to see if the PF has ACK'd
352 * @hw: pointer to the HW structure
353 * @mbx_id: id of mailbox to check
354 *
355 * returns SUCCESS if the PF has set the ACK bit or else ERR_MBX
356 **/
357static s32 ixgbe_check_for_ack_vf(struct ixgbe_hw *hw, u16 mbx_id)
358{
359	s32 ret_val = IXGBE_ERR_MBX;
360
361	UNREFERENCED_1PARAMETER(mbx_id);
362	DEBUGFUNC("ixgbe_check_for_ack_vf");
363
364	if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFACK)) {
365		ret_val = IXGBE_SUCCESS;
366		hw->mbx.stats.acks++;
367	}
368
369	return ret_val;
370}
371
372/**
373 * ixgbe_check_for_rst_vf - checks to see if the PF has reset
374 * @hw: pointer to the HW structure
375 * @mbx_id: id of mailbox to check
376 *
377 * returns true if the PF has set the reset done bit or else false
378 **/
379static s32 ixgbe_check_for_rst_vf(struct ixgbe_hw *hw, u16 mbx_id)
380{
381	s32 ret_val = IXGBE_ERR_MBX;
382
383	UNREFERENCED_1PARAMETER(mbx_id);
384	DEBUGFUNC("ixgbe_check_for_rst_vf");
385
386	if (!ixgbe_check_for_bit_vf(hw, (IXGBE_VFMAILBOX_RSTD |
387	    IXGBE_VFMAILBOX_RSTI))) {
388		ret_val = IXGBE_SUCCESS;
389		hw->mbx.stats.rsts++;
390	}
391
392	return ret_val;
393}
394
395/**
396 * ixgbe_obtain_mbx_lock_vf - obtain mailbox lock
397 * @hw: pointer to the HW structure
398 *
399 * return SUCCESS if we obtained the mailbox lock
400 **/
401static s32 ixgbe_obtain_mbx_lock_vf(struct ixgbe_hw *hw)
402{
403	s32 ret_val = IXGBE_ERR_MBX;
404
405	DEBUGFUNC("ixgbe_obtain_mbx_lock_vf");
406
407	/* Take ownership of the buffer */
408	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_VFU);
409
410	/* reserve mailbox for vf use */
411	if (ixgbe_read_v2p_mailbox(hw) & IXGBE_VFMAILBOX_VFU)
412		ret_val = IXGBE_SUCCESS;
413
414	return ret_val;
415}
416
417/**
418 * ixgbe_write_mbx_vf - Write a message to the mailbox
419 * @hw: pointer to the HW structure
420 * @msg: The message buffer
421 * @size: Length of buffer
422 * @mbx_id: id of mailbox to write
423 *
424 * returns SUCCESS if it successfully copied message into the buffer
425 **/
426static s32 ixgbe_write_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,
427			      u16 mbx_id)
428{
429	s32 ret_val;
430	u16 i;
431
432	UNREFERENCED_1PARAMETER(mbx_id);
433
434	DEBUGFUNC("ixgbe_write_mbx_vf");
435
436	/* lock the mailbox to prevent pf/vf race condition */
437	ret_val = ixgbe_obtain_mbx_lock_vf(hw);
438	if (ret_val)
439		goto out_no_write;
440
441	/* flush msg and acks as we are overwriting the message buffer */
442	ixgbe_check_for_msg_vf(hw, 0);
443	ixgbe_check_for_ack_vf(hw, 0);
444
445	/* copy the caller specified message to the mailbox memory buffer */
446	for (i = 0; i < size; i++)
447		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFMBMEM, i, msg[i]);
448
449	/* update stats */
450	hw->mbx.stats.msgs_tx++;
451
452	/* Drop VFU and interrupt the PF to tell it a message has been sent */
453	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_REQ);
454
455out_no_write:
456	return ret_val;
457}
458
459/**
460 * ixgbe_read_mbx_vf - Reads a message from the inbox intended for vf
461 * @hw: pointer to the HW structure
462 * @msg: The message buffer
463 * @size: Length of buffer
464 * @mbx_id: id of mailbox to read
465 *
466 * returns SUCCESS if it successfully read message from buffer
467 **/
468static s32 ixgbe_read_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,
469			     u16 mbx_id)
470{
471	s32 ret_val = IXGBE_SUCCESS;
472	u16 i;
473
474	DEBUGFUNC("ixgbe_read_mbx_vf");
475	UNREFERENCED_1PARAMETER(mbx_id);
476
477	/* lock the mailbox to prevent pf/vf race condition */
478	ret_val = ixgbe_obtain_mbx_lock_vf(hw);
479	if (ret_val)
480		goto out_no_read;
481
482	/* copy the message from the mailbox memory buffer */
483	for (i = 0; i < size; i++)
484		msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i);
485
486	/* Acknowledge receipt and release mailbox, then we're done */
487	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_ACK);
488
489	/* update stats */
490	hw->mbx.stats.msgs_rx++;
491
492out_no_read:
493	return ret_val;
494}
495
496/**
497 * ixgbe_init_mbx_params_vf - set initial values for vf mailbox
498 * @hw: pointer to the HW structure
499 *
500 * Initializes the hw->mbx struct to correct values for vf mailbox
501 */
502void ixgbe_init_mbx_params_vf(struct ixgbe_hw *hw)
503{
504	struct ixgbe_mbx_info *mbx = &hw->mbx;
505
506	/* start mailbox as timed out and let the reset_hw call set the timeout
507	 * value to begin communications */
508	mbx->timeout = 0;
509	mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;
510
511	mbx->size = IXGBE_VFMAILBOX_SIZE;
512
513	mbx->ops.read = ixgbe_read_mbx_vf;
514	mbx->ops.write = ixgbe_write_mbx_vf;
515	mbx->ops.read_posted = ixgbe_read_posted_mbx;
516	mbx->ops.write_posted = ixgbe_write_posted_mbx;
517	mbx->ops.check_for_msg = ixgbe_check_for_msg_vf;
518	mbx->ops.check_for_ack = ixgbe_check_for_ack_vf;
519	mbx->ops.check_for_rst = ixgbe_check_for_rst_vf;
520
521	mbx->stats.msgs_tx = 0;
522	mbx->stats.msgs_rx = 0;
523	mbx->stats.reqs = 0;
524	mbx->stats.acks = 0;
525	mbx->stats.rsts = 0;
526}
527
528static s32 ixgbe_check_for_bit_pf(struct ixgbe_hw *hw, u32 mask, s32 index)
529{
530	u32 mbvficr = IXGBE_READ_REG(hw, IXGBE_MBVFICR(index));
531	s32 ret_val = IXGBE_ERR_MBX;
532
533	if (mbvficr & mask) {
534		ret_val = IXGBE_SUCCESS;
535		IXGBE_WRITE_REG(hw, IXGBE_MBVFICR(index), mask);
536	}
537
538	return ret_val;
539}
540
541/**
542 * ixgbe_check_for_msg_pf - checks to see if the VF has sent mail
543 * @hw: pointer to the HW structure
544 * @vf_number: the VF index
545 *
546 * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
547 **/
548static s32 ixgbe_check_for_msg_pf(struct ixgbe_hw *hw, u16 vf_number)
549{
550	s32 ret_val = IXGBE_ERR_MBX;
551	s32 index = IXGBE_MBVFICR_INDEX(vf_number);
552	u32 vf_bit = vf_number % 16;
553
554	DEBUGFUNC("ixgbe_check_for_msg_pf");
555
556	if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFREQ_VF1 << vf_bit,
557				    index)) {
558		ret_val = IXGBE_SUCCESS;
559		hw->mbx.stats.reqs++;
560	}
561
562	return ret_val;
563}
564
565/**
566 * ixgbe_check_for_ack_pf - checks to see if the VF has ACKed
567 * @hw: pointer to the HW structure
568 * @vf_number: the VF index
569 *
570 * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
571 **/
572static s32 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_number)
573{
574	s32 ret_val = IXGBE_ERR_MBX;
575	s32 index = IXGBE_MBVFICR_INDEX(vf_number);
576	u32 vf_bit = vf_number % 16;
577
578	DEBUGFUNC("ixgbe_check_for_ack_pf");
579
580	if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFACK_VF1 << vf_bit,
581				    index)) {
582		ret_val = IXGBE_SUCCESS;
583		hw->mbx.stats.acks++;
584	}
585
586	return ret_val;
587}
588
589/**
590 * ixgbe_check_for_rst_pf - checks to see if the VF has reset
591 * @hw: pointer to the HW structure
592 * @vf_number: the VF index
593 *
594 * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
595 **/
596static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_number)
597{
598	u32 reg_offset = (vf_number < 32) ? 0 : 1;
599	u32 vf_shift = vf_number % 32;
600	u32 vflre = 0;
601	s32 ret_val = IXGBE_ERR_MBX;
602
603	DEBUGFUNC("ixgbe_check_for_rst_pf");
604
605	switch (hw->mac.type) {
606	case ixgbe_mac_82599EB:
607		vflre = IXGBE_READ_REG(hw, IXGBE_VFLRE(reg_offset));
608		break;
609	case ixgbe_mac_X550:
610	case ixgbe_mac_X550EM_x:
611	case ixgbe_mac_X550EM_a:
612	case ixgbe_mac_X540:
613		vflre = IXGBE_READ_REG(hw, IXGBE_VFLREC(reg_offset));
614		break;
615	default:
616		break;
617	}
618
619	if (vflre & (1 << vf_shift)) {
620		ret_val = IXGBE_SUCCESS;
621		IXGBE_WRITE_REG(hw, IXGBE_VFLREC(reg_offset), (1 << vf_shift));
622		hw->mbx.stats.rsts++;
623	}
624
625	return ret_val;
626}
627
628/**
629 * ixgbe_obtain_mbx_lock_pf - obtain mailbox lock
630 * @hw: pointer to the HW structure
631 * @vf_number: the VF index
632 *
633 * return SUCCESS if we obtained the mailbox lock
634 **/
635static s32 ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_number)
636{
637	s32 ret_val = IXGBE_ERR_MBX;
638	u32 p2v_mailbox;
639
640	DEBUGFUNC("ixgbe_obtain_mbx_lock_pf");
641
642	/* Take ownership of the buffer */
643	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_PFU);
644
645	/* reserve mailbox for vf use */
646	p2v_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_number));
647	if (p2v_mailbox & IXGBE_PFMAILBOX_PFU)
648		ret_val = IXGBE_SUCCESS;
649	else
650		ERROR_REPORT2(IXGBE_ERROR_POLLING,
651			   "Failed to obtain mailbox lock for VF%d", vf_number);
652
653
654	return ret_val;
655}
656
657/**
658 * ixgbe_write_mbx_pf - Places a message in the mailbox
659 * @hw: pointer to the HW structure
660 * @msg: The message buffer
661 * @size: Length of buffer
662 * @vf_number: the VF index
663 *
664 * returns SUCCESS if it successfully copied message into the buffer
665 **/
666static s32 ixgbe_write_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
667			      u16 vf_number)
668{
669	s32 ret_val;
670	u16 i;
671
672	DEBUGFUNC("ixgbe_write_mbx_pf");
673
674	/* lock the mailbox to prevent pf/vf race condition */
675	ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number);
676	if (ret_val)
677		goto out_no_write;
678
679	/* flush msg and acks as we are overwriting the message buffer */
680	ixgbe_check_for_msg_pf(hw, vf_number);
681	ixgbe_check_for_ack_pf(hw, vf_number);
682
683	/* copy the caller specified message to the mailbox memory buffer */
684	for (i = 0; i < size; i++)
685		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i, msg[i]);
686
687	/* Interrupt VF to tell it a message has been sent and release buffer*/
688	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_STS);
689
690	/* update stats */
691	hw->mbx.stats.msgs_tx++;
692
693out_no_write:
694	return ret_val;
695
696}
697
698/**
699 * ixgbe_read_mbx_pf - Read a message from the mailbox
700 * @hw: pointer to the HW structure
701 * @msg: The message buffer
702 * @size: Length of buffer
703 * @vf_number: the VF index
704 *
705 * This function copies a message from the mailbox buffer to the caller's
706 * memory buffer.  The presumption is that the caller knows that there was
707 * a message due to a VF request so no polling for message is needed.
708 **/
709static s32 ixgbe_read_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
710			     u16 vf_number)
711{
712	s32 ret_val;
713	u16 i;
714
715	DEBUGFUNC("ixgbe_read_mbx_pf");
716
717	/* lock the mailbox to prevent pf/vf race condition */
718	ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number);
719	if (ret_val)
720		goto out_no_read;
721
722	/* copy the message to the mailbox memory buffer */
723	for (i = 0; i < size; i++)
724		msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i);
725
726	/* Acknowledge the message and release buffer */
727	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_ACK);
728
729	/* update stats */
730	hw->mbx.stats.msgs_rx++;
731
732out_no_read:
733	return ret_val;
734}
735
736/**
737 * ixgbe_init_mbx_params_pf - set initial values for pf mailbox
738 * @hw: pointer to the HW structure
739 *
740 * Initializes the hw->mbx struct to correct values for pf mailbox
741 */
742void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw)
743{
744	struct ixgbe_mbx_info *mbx = &hw->mbx;
745
746	if (hw->mac.type != ixgbe_mac_82599EB &&
747	    hw->mac.type != ixgbe_mac_X550 &&
748	    hw->mac.type != ixgbe_mac_X550EM_x &&
749	    hw->mac.type != ixgbe_mac_X550EM_a &&
750	    hw->mac.type != ixgbe_mac_X540)
751		return;
752
753	mbx->timeout = 0;
754	mbx->usec_delay = 0;
755
756	mbx->size = IXGBE_VFMAILBOX_SIZE;
757
758	mbx->ops.read = ixgbe_read_mbx_pf;
759	mbx->ops.write = ixgbe_write_mbx_pf;
760	mbx->ops.read_posted = ixgbe_read_posted_mbx;
761	mbx->ops.write_posted = ixgbe_write_posted_mbx;
762	mbx->ops.check_for_msg = ixgbe_check_for_msg_pf;
763	mbx->ops.check_for_ack = ixgbe_check_for_ack_pf;
764	mbx->ops.check_for_rst = ixgbe_check_for_rst_pf;
765
766	mbx->stats.msgs_tx = 0;
767	mbx->stats.msgs_rx = 0;
768	mbx->stats.reqs = 0;
769	mbx->stats.acks = 0;
770	mbx->stats.rsts = 0;
771}
772