ixgbe_mbx.c revision 283620
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: stable/10/sys/dev/ixgbe/ixgbe_mbx.c 283620 2015-05-27 17:44:11Z erj $*/
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 **/
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 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 **/
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, 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);
239out:
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 **/
253s32 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);
271out:
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 **/
281void 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 **/
296static 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 **/
314static 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 **/
334static 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 **/
356static 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 **/
378static 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 **/
400static 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 **/
425static 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
454out_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 successfuly read message from buffer
466 **/
467static 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
491out_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 */
501void 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
527static 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 **/
547static 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 **/
571static 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 **/
595static 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 **/
633static 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 **/
664static 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
691out_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 **/
707static 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
730out_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 */
740void 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