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