xref: /netbsd-src/sys/dev/pci/ixgbe/ixgbe_mbx.c (revision 2edbe6eb413ca8f650e4e9356aaa65de418f1fcf)
1 /* $NetBSD: ixgbe_mbx.c,v 1.19 2022/01/25 01:56:22 msaitoh Exp $ */
2 
3 /******************************************************************************
4   SPDX-License-Identifier: BSD-3-Clause
5 
6   Copyright (c) 2001-2020, Intel Corporation
7   All rights reserved.
8 
9   Redistribution and use in source and binary forms, with or without
10   modification, are permitted provided that the following conditions are met:
11 
12    1. Redistributions of source code must retain the above copyright notice,
13       this list of conditions and the following disclaimer.
14 
15    2. Redistributions in binary form must reproduce the above copyright
16       notice, this list of conditions and the following disclaimer in the
17       documentation and/or other materials provided with the distribution.
18 
19    3. Neither the name of the Intel Corporation nor the names of its
20       contributors may be used to endorse or promote products derived from
21       this software without specific prior written permission.
22 
23   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33   POSSIBILITY OF SUCH DAMAGE.
34 
35 ******************************************************************************/
36 /*$FreeBSD: head/sys/dev/ixgbe/ixgbe_mbx.c 326022 2017-11-20 19:36:21Z pfg $*/
37 
38 #include <sys/cdefs.h>
39 __KERNEL_RCSID(0, "$NetBSD: ixgbe_mbx.c,v 1.19 2022/01/25 01:56:22 msaitoh Exp $");
40 
41 #include "ixgbe_type.h"
42 #include "ixgbe_netbsd.h"
43 #include "ixgbe_mbx.h"
44 
45 static s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id);
46 static s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id);
47 
48 /**
49  * ixgbe_read_mbx - Reads a message from the mailbox
50  * @hw: pointer to the HW structure
51  * @msg: The message buffer
52  * @size: Length of buffer
53  * @mbx_id: id of mailbox to read
54  *
55  * returns SUCCESS if it successfully read message from buffer
56  **/
ixgbe_read_mbx(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 mbx_id)57 s32 ixgbe_read_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
58 {
59 	struct ixgbe_mbx_info *mbx = &hw->mbx;
60 
61 	DEBUGFUNC("ixgbe_read_mbx");
62 
63 	/* limit read to size of mailbox */
64 	if (size > mbx->size) {
65 		ERROR_REPORT3(IXGBE_ERROR_ARGUMENT,
66 			      "Invalid mailbox message size %u, changing to %u",
67 			      size, mbx->size);
68 		size = mbx->size;
69 	}
70 
71 	if (mbx->ops[mbx_id].read)
72 		return mbx->ops[mbx_id].read(hw, msg, size, mbx_id);
73 
74 	return IXGBE_ERR_CONFIG;
75 }
76 
77 /**
78  * ixgbe_poll_mbx - Wait for message and read it from the mailbox
79  * @hw: pointer to the HW structure
80  * @msg: The message buffer
81  * @size: Length of buffer
82  * @mbx_id: id of mailbox to read
83  *
84  * returns SUCCESS if it successfully read message from buffer
85  **/
ixgbe_poll_mbx(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 mbx_id)86 s32 ixgbe_poll_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
87 {
88 	struct ixgbe_mbx_info *mbx = &hw->mbx;
89 	s32 ret_val;
90 
91 	DEBUGFUNC("ixgbe_poll_mbx");
92 
93 	if (!mbx->ops[mbx_id].read || !mbx->ops[mbx_id].check_for_msg ||
94 	    !mbx->timeout)
95 		return IXGBE_ERR_CONFIG;
96 
97 	/* limit read to size of mailbox */
98 	if (size > mbx->size) {
99 		ERROR_REPORT3(IXGBE_ERROR_ARGUMENT,
100 			      "Invalid mailbox message size %u, changing to %u",
101 			      size, mbx->size);
102 		size = mbx->size;
103 	}
104 
105 	ret_val = ixgbe_poll_for_msg(hw, mbx_id);
106 	/* if ack received read message, otherwise we timed out */
107 	if (!ret_val)
108 		return mbx->ops[mbx_id].read(hw, msg, size, mbx_id);
109 
110 	return ret_val;
111 }
112 
113 /**
114  * ixgbe_write_mbx - Write a message to the mailbox and wait for ACK
115  * @hw: pointer to the HW structure
116  * @msg: The message buffer
117  * @size: Length of buffer
118  * @mbx_id: id of mailbox to write
119  *
120  * returns SUCCESS if it successfully copied message into the buffer and
121  * received an ACK to that message within specified period
122  **/
ixgbe_write_mbx(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 mbx_id)123 s32 ixgbe_write_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
124 {
125 	struct ixgbe_mbx_info *mbx = &hw->mbx;
126 	s32 ret_val = IXGBE_ERR_MBX;
127 
128 	DEBUGFUNC("ixgbe_write_mbx");
129 
130 	/*
131 	 * exit if either we can't write, release
132 	 * or there is no timeout defined
133 	 */
134 	if (!mbx->ops[mbx_id].write || !mbx->ops[mbx_id].check_for_ack ||
135 	    !mbx->ops[mbx_id].release || !mbx->timeout)
136 		return IXGBE_ERR_CONFIG;
137 
138 	if (size > mbx->size) {
139 		ret_val = IXGBE_ERR_PARAM;
140 		ERROR_REPORT2(IXGBE_ERROR_ARGUMENT,
141 			     "Invalid mailbox message size %u", size);
142 	} else {
143 		ret_val = mbx->ops[mbx_id].write(hw, msg, size, mbx_id);
144 	}
145 
146 	return ret_val;
147 }
148 
149 /**
150  * ixgbe_check_for_msg - checks to see if someone sent us mail
151  * @hw: pointer to the HW structure
152  * @mbx_id: id of mailbox to check
153  *
154  * returns SUCCESS if the Status bit was found or else ERR_MBX
155  **/
ixgbe_check_for_msg(struct ixgbe_hw * hw,u16 mbx_id)156 s32 ixgbe_check_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
157 {
158 	struct ixgbe_mbx_info *mbx = &hw->mbx;
159 	s32 ret_val = IXGBE_ERR_CONFIG;
160 
161 	DEBUGFUNC("ixgbe_check_for_msg");
162 
163 	if (mbx->ops[mbx_id].check_for_msg)
164 		ret_val = mbx->ops[mbx_id].check_for_msg(hw, mbx_id);
165 
166 	return ret_val;
167 }
168 
169 /**
170  * ixgbe_check_for_ack - checks to see if someone sent us ACK
171  * @hw: pointer to the HW structure
172  * @mbx_id: id of mailbox to check
173  *
174  * returns SUCCESS if the Status bit was found or else ERR_MBX
175  **/
ixgbe_check_for_ack(struct ixgbe_hw * hw,u16 mbx_id)176 s32 ixgbe_check_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
177 {
178 	struct ixgbe_mbx_info *mbx = &hw->mbx;
179 	s32 ret_val = IXGBE_ERR_CONFIG;
180 
181 	DEBUGFUNC("ixgbe_check_for_ack");
182 
183 	if (mbx->ops[mbx_id].check_for_ack)
184 		ret_val = mbx->ops[mbx_id].check_for_ack(hw, mbx_id);
185 
186 	return ret_val;
187 }
188 
189 /**
190  * ixgbe_check_for_rst - checks to see if other side has reset
191  * @hw: pointer to the HW structure
192  * @mbx_id: id of mailbox to check
193  *
194  * returns SUCCESS if the Status bit was found or else ERR_MBX
195  **/
ixgbe_check_for_rst(struct ixgbe_hw * hw,u16 mbx_id)196 s32 ixgbe_check_for_rst(struct ixgbe_hw *hw, u16 mbx_id)
197 {
198 	struct ixgbe_mbx_info *mbx = &hw->mbx;
199 	s32 ret_val = IXGBE_ERR_CONFIG;
200 
201 	DEBUGFUNC("ixgbe_check_for_rst");
202 
203 	if (mbx->ops[mbx_id].check_for_rst)
204 		ret_val = mbx->ops[mbx_id].check_for_rst(hw, mbx_id);
205 
206 	return ret_val;
207 }
208 
209 /**
210  * ixgbe_clear_mbx - Clear Mailbox Memory
211  * @hw: pointer to the HW structure
212  * @mbx_id: id of mailbox to write
213  *
214  * Set VFMBMEM of given VF to 0x0.
215  **/
ixgbe_clear_mbx(struct ixgbe_hw * hw,u16 mbx_id)216 s32 ixgbe_clear_mbx(struct ixgbe_hw *hw, u16 mbx_id)
217 {
218 	struct ixgbe_mbx_info *mbx = &hw->mbx;
219 	s32 ret_val = IXGBE_ERR_CONFIG;
220 
221 	DEBUGFUNC("ixgbe_clear_mbx");
222 
223 	if (mbx->ops[mbx_id].clear)
224 		ret_val = mbx->ops[mbx_id].clear(hw, mbx_id);
225 
226 	return ret_val;
227 }
228 
229 /**
230  * ixgbe_poll_for_msg - Wait for message notification
231  * @hw: pointer to the HW structure
232  * @mbx_id: id of mailbox to write
233  *
234  * returns SUCCESS if it successfully received a message notification
235  **/
ixgbe_poll_for_msg(struct ixgbe_hw * hw,u16 mbx_id)236 static s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
237 {
238 	struct ixgbe_mbx_info *mbx = &hw->mbx;
239 	int countdown = mbx->timeout;
240 
241 	DEBUGFUNC("ixgbe_poll_for_msg");
242 
243 	if (!countdown || !mbx->ops[mbx_id].check_for_msg)
244 		return IXGBE_ERR_CONFIG;
245 
246 	while (countdown && mbx->ops[mbx_id].check_for_msg(hw, mbx_id)) {
247 		countdown--;
248 		if (!countdown)
249 			break;
250 		usec_delay(mbx->usec_delay);
251 	}
252 
253 	if (countdown == 0) {
254 		ERROR_REPORT2(IXGBE_ERROR_POLLING,
255 			   "Polling for VF%u mailbox message timedout", mbx_id);
256 		return IXGBE_ERR_TIMEOUT;
257 	}
258 
259 	return IXGBE_SUCCESS;
260 }
261 
262 /**
263  * ixgbe_poll_for_ack - Wait for message acknowledgment
264  * @hw: pointer to the HW structure
265  * @mbx_id: id of mailbox to write
266  *
267  * returns SUCCESS if it successfully received a message acknowledgment
268  **/
ixgbe_poll_for_ack(struct ixgbe_hw * hw,u16 mbx_id)269 static s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
270 {
271 	struct ixgbe_mbx_info *mbx = &hw->mbx;
272 	int countdown = mbx->timeout;
273 
274 	DEBUGFUNC("ixgbe_poll_for_ack");
275 
276 	if (!countdown || !mbx->ops[mbx_id].check_for_ack)
277 		return IXGBE_ERR_CONFIG;
278 
279 	while (countdown && mbx->ops[mbx_id].check_for_ack(hw, mbx_id)) {
280 		countdown--;
281 		if (!countdown)
282 			break;
283 		usec_delay(mbx->usec_delay);
284 	}
285 
286 	if (countdown == 0) {
287 		ERROR_REPORT2(IXGBE_ERROR_POLLING,
288 			     "Polling for VF%u mailbox ack timedout", mbx_id);
289 		return IXGBE_ERR_TIMEOUT;
290 	}
291 
292 	return IXGBE_SUCCESS;
293 }
294 
295 
296 /**
297  * ixgbe_read_mailbox_vf - read VF's mailbox register
298  * @hw: pointer to the HW structure
299  *
300  * This function is used to read the mailbox register dedicated for VF without
301  * losing the read to clear status bits.
302  **/
ixgbe_read_mailbox_vf(struct ixgbe_hw * hw)303 static u32 ixgbe_read_mailbox_vf(struct ixgbe_hw *hw)
304 {
305 	u32 vf_mailbox = IXGBE_READ_REG(hw, IXGBE_VFMAILBOX);
306 
307 	vf_mailbox |= hw->mbx.vf_mailbox;
308 	hw->mbx.vf_mailbox |= vf_mailbox & IXGBE_VFMAILBOX_R2C_BITS;
309 
310 	return vf_mailbox;
311 }
312 
ixgbe_clear_msg_vf(struct ixgbe_hw * hw)313 static void ixgbe_clear_msg_vf(struct ixgbe_hw *hw)
314 {
315 	u32 vf_mailbox = ixgbe_read_mailbox_vf(hw);
316 
317 	if (vf_mailbox & IXGBE_VFMAILBOX_PFSTS) {
318 		IXGBE_EVC_ADD(&hw->mbx.stats.reqs, 1);
319 		hw->mbx.vf_mailbox &= ~IXGBE_VFMAILBOX_PFSTS;
320 	}
321 }
322 
ixgbe_clear_ack_vf(struct ixgbe_hw * hw)323 static void ixgbe_clear_ack_vf(struct ixgbe_hw *hw)
324 {
325 	u32 vf_mailbox = ixgbe_read_mailbox_vf(hw);
326 
327 	if (vf_mailbox & IXGBE_VFMAILBOX_PFACK) {
328 		IXGBE_EVC_ADD(&hw->mbx.stats.acks, 1);
329 		hw->mbx.vf_mailbox &= ~IXGBE_VFMAILBOX_PFACK;
330 	}
331 }
332 
ixgbe_clear_rst_vf(struct ixgbe_hw * hw)333 static void ixgbe_clear_rst_vf(struct ixgbe_hw *hw)
334 {
335 	u32 vf_mailbox = ixgbe_read_mailbox_vf(hw);
336 
337 	if (vf_mailbox & (IXGBE_VFMAILBOX_RSTI | IXGBE_VFMAILBOX_RSTD)) {
338 		IXGBE_EVC_ADD(&hw->mbx.stats.rsts, 1);
339 		hw->mbx.vf_mailbox &= ~(IXGBE_VFMAILBOX_RSTI |
340 					IXGBE_VFMAILBOX_RSTD);
341 	}
342 }
343 
344 /**
345  * ixgbe_check_for_bit_vf - Determine if a status bit was set
346  * @hw: pointer to the HW structure
347  * @mask: bitmask for bits to be tested and cleared
348  *
349  * This function is used to check for the read to clear bits within
350  * the V2P mailbox.
351  **/
ixgbe_check_for_bit_vf(struct ixgbe_hw * hw,u32 mask)352 static s32 ixgbe_check_for_bit_vf(struct ixgbe_hw *hw, u32 mask)
353 {
354 	u32 vf_mailbox = ixgbe_read_mailbox_vf(hw);
355 
356 	if (vf_mailbox & mask)
357 		return IXGBE_SUCCESS;
358 
359 	return IXGBE_ERR_MBX;
360 }
361 
362 /**
363  * ixgbe_check_for_msg_vf - checks to see if the PF has sent mail
364  * @hw: pointer to the HW structure
365  * @mbx_id: id of mailbox to check
366  *
367  * returns SUCCESS if the PF has set the Status bit or else ERR_MBX
368  **/
ixgbe_check_for_msg_vf(struct ixgbe_hw * hw,u16 mbx_id)369 static s32 ixgbe_check_for_msg_vf(struct ixgbe_hw *hw, u16 mbx_id)
370 {
371 	UNREFERENCED_1PARAMETER(mbx_id);
372 	DEBUGFUNC("ixgbe_check_for_msg_vf");
373 
374 	if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFSTS)) {
375 		IXGBE_EVC_ADD(&hw->mbx.stats.reqs, 1);
376 		return IXGBE_SUCCESS;
377 	}
378 
379 	return IXGBE_ERR_MBX;
380 }
381 
382 /**
383  * ixgbe_check_for_ack_vf - checks to see if the PF has ACK'd
384  * @hw: pointer to the HW structure
385  * @mbx_id: id of mailbox to check
386  *
387  * returns SUCCESS if the PF has set the ACK bit or else ERR_MBX
388  **/
ixgbe_check_for_ack_vf(struct ixgbe_hw * hw,u16 mbx_id)389 static s32 ixgbe_check_for_ack_vf(struct ixgbe_hw *hw, u16 mbx_id)
390 {
391 	UNREFERENCED_1PARAMETER(mbx_id);
392 	DEBUGFUNC("ixgbe_check_for_ack_vf");
393 
394 	if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFACK)) {
395 		/* TODO: should this be autocleared? */
396 		ixgbe_clear_ack_vf(hw);
397 		IXGBE_EVC_ADD(&hw->mbx.stats.acks, 1);
398 		return IXGBE_SUCCESS;
399 	}
400 
401 	return IXGBE_ERR_MBX;
402 }
403 
404 /**
405  * ixgbe_check_for_rst_vf - checks to see if the PF has reset
406  * @hw: pointer to the HW structure
407  * @mbx_id: id of mailbox to check
408  *
409  * returns TRUE if the PF has set the reset done bit or else FALSE
410  **/
ixgbe_check_for_rst_vf(struct ixgbe_hw * hw,u16 mbx_id)411 static s32 ixgbe_check_for_rst_vf(struct ixgbe_hw *hw, u16 mbx_id)
412 {
413 	UNREFERENCED_1PARAMETER(mbx_id);
414 	DEBUGFUNC("ixgbe_check_for_rst_vf");
415 
416 	if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_RSTI |
417 					  IXGBE_VFMAILBOX_RSTD)) {
418 		/* TODO: should this be autocleared? */
419 		ixgbe_clear_rst_vf(hw);
420 		IXGBE_EVC_ADD(&hw->mbx.stats.rsts, 1);
421 		return IXGBE_SUCCESS;
422 	}
423 
424 	return IXGBE_ERR_MBX;
425 }
426 
427 /**
428  * ixgbe_obtain_mbx_lock_vf - obtain mailbox lock
429  * @hw: pointer to the HW structure
430  *
431  * return SUCCESS if we obtained the mailbox lock
432  **/
ixgbe_obtain_mbx_lock_vf(struct ixgbe_hw * hw)433 static s32 ixgbe_obtain_mbx_lock_vf(struct ixgbe_hw *hw)
434 {
435 	struct ixgbe_mbx_info *mbx = &hw->mbx;
436 	int countdown = mbx->timeout;
437 	s32 ret_val = IXGBE_ERR_MBX;
438 	u32 vf_mailbox;
439 
440 	DEBUGFUNC("ixgbe_obtain_mbx_lock_vf");
441 
442 	if (!mbx->timeout)
443 		return IXGBE_ERR_CONFIG;
444 
445 	while (countdown--) {
446 		/* Reserve mailbox for VF use */
447 		vf_mailbox = ixgbe_read_mailbox_vf(hw);
448 		vf_mailbox |= IXGBE_VFMAILBOX_VFU;
449 		IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox);
450 
451 		/* Verify that VF is the owner of the lock */
452 		if (ixgbe_read_mailbox_vf(hw) & IXGBE_VFMAILBOX_VFU) {
453 			ret_val = IXGBE_SUCCESS;
454 			break;
455 		}
456 
457 		/* Wait a bit before trying again */
458 		usec_delay(mbx->usec_delay);
459 	}
460 
461 	if (ret_val != IXGBE_SUCCESS) {
462 		ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
463 				"Failed to obtain mailbox lock");
464 		ret_val = IXGBE_ERR_TIMEOUT;
465 	}
466 
467 	return ret_val;
468 }
469 
470 /**
471  * ixgbe_release_mbx_lock_dummy - release mailbox lock
472  * @hw: pointer to the HW structure
473  * @mbx_id: id of mailbox to read
474  **/
ixgbe_release_mbx_lock_dummy(struct ixgbe_hw * hw,u16 mbx_id)475 static void ixgbe_release_mbx_lock_dummy(struct ixgbe_hw *hw, u16 mbx_id)
476 {
477 	UNREFERENCED_2PARAMETER(hw, mbx_id);
478 
479 	DEBUGFUNC("ixgbe_release_mbx_lock_dummy");
480 }
481 
482 /**
483  * ixgbe_release_mbx_lock_vf - release mailbox lock
484  * @hw: pointer to the HW structure
485  * @mbx_id: id of mailbox to read
486  **/
ixgbe_release_mbx_lock_vf(struct ixgbe_hw * hw,u16 mbx_id)487 static void ixgbe_release_mbx_lock_vf(struct ixgbe_hw *hw, u16 mbx_id)
488 {
489 	u32 vf_mailbox;
490 
491 	UNREFERENCED_1PARAMETER(mbx_id);
492 
493 	DEBUGFUNC("ixgbe_release_mbx_lock_vf");
494 
495 	/* Return ownership of the buffer */
496 	vf_mailbox = ixgbe_read_mailbox_vf(hw);
497 	vf_mailbox &= ~IXGBE_VFMAILBOX_VFU;
498 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox);
499 }
500 
501 /**
502  * ixgbe_write_mbx_vf_legacy - Write a message to the mailbox
503  * @hw: pointer to the HW structure
504  * @msg: The message buffer
505  * @size: Length of buffer
506  * @mbx_id: id of mailbox to write
507  *
508  * returns SUCCESS if it successfully copied message into the buffer
509  **/
ixgbe_write_mbx_vf_legacy(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 mbx_id)510 static s32 ixgbe_write_mbx_vf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size,
511 				     u16 mbx_id)
512 {
513 	s32 ret_val;
514 	u16 i;
515 
516 	UNREFERENCED_1PARAMETER(mbx_id);
517 	DEBUGFUNC("ixgbe_write_mbx_vf_legacy");
518 
519 	/* lock the mailbox to prevent pf/vf race condition */
520 	ret_val = ixgbe_obtain_mbx_lock_vf(hw);
521 	if (ret_val)
522 		return ret_val;
523 
524 	/* flush msg and acks as we are overwriting the message buffer */
525 	ixgbe_check_for_msg_vf(hw, 0);
526 	ixgbe_clear_msg_vf(hw);
527 	ixgbe_check_for_ack_vf(hw, 0);
528 	ixgbe_clear_ack_vf(hw);
529 
530 	/* copy the caller specified message to the mailbox memory buffer */
531 	for (i = 0; i < size; i++)
532 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFMBMEM, i, msg[i]);
533 
534 	/* update stats */
535 	IXGBE_EVC_ADD(&hw->mbx.stats.msgs_tx, 1);
536 
537 	/* interrupt the PF to tell it a message has been sent */
538 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_REQ);
539 
540 	return IXGBE_SUCCESS;
541 }
542 
543 /**
544  * ixgbe_write_mbx_vf - Write a message to the mailbox
545  * @hw: pointer to the HW structure
546  * @msg: The message buffer
547  * @size: Length of buffer
548  * @mbx_id: id of mailbox to write
549  *
550  * returns SUCCESS if it successfully copied message into the buffer
551  **/
ixgbe_write_mbx_vf(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 mbx_id)552 static s32 ixgbe_write_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,
553 			      u16 mbx_id)
554 {
555 	u32 vf_mailbox;
556 	s32 ret_val;
557 	u16 i;
558 
559 	UNREFERENCED_1PARAMETER(mbx_id);
560 
561 	DEBUGFUNC("ixgbe_write_mbx_vf");
562 
563 	/* lock the mailbox to prevent pf/vf race condition */
564 	ret_val = ixgbe_obtain_mbx_lock_vf(hw);
565 	if (ret_val)
566 		goto out;
567 
568 	/* flush msg and acks as we are overwriting the message buffer */
569 	ixgbe_clear_msg_vf(hw);
570 	ixgbe_clear_ack_vf(hw);
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_VFMBMEM, i, msg[i]);
575 
576 	/* update stats */
577 	IXGBE_EVC_ADD(&hw->mbx.stats.msgs_tx, 1);
578 
579 	/* interrupt the PF to tell it a message has been sent */
580 	vf_mailbox = ixgbe_read_mailbox_vf(hw);
581 	vf_mailbox |= IXGBE_VFMAILBOX_REQ;
582 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox);
583 
584 	/* if msg sent wait until we receive an ack */
585 	ixgbe_poll_for_ack(hw, mbx_id);
586 
587 out:
588 	hw->mbx.ops[mbx_id].release(hw, mbx_id);
589 
590 	return ret_val;
591 }
592 
593 /**
594  * ixgbe_read_mbx_vf_legacy - Reads a message from the inbox intended for vf
595  * @hw: pointer to the HW structure
596  * @msg: The message buffer
597  * @size: Length of buffer
598  * @mbx_id: id of mailbox to read
599  *
600  * returns SUCCESS if it successfully read message from buffer
601  **/
ixgbe_read_mbx_vf_legacy(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 mbx_id)602 static s32 ixgbe_read_mbx_vf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size,
603 				    u16 mbx_id)
604 {
605 	s32 ret_val;
606 	u16 i;
607 
608 	DEBUGFUNC("ixgbe_read_mbx_vf_legacy");
609 	UNREFERENCED_1PARAMETER(mbx_id);
610 
611 	/* lock the mailbox to prevent pf/vf race condition */
612 	ret_val = ixgbe_obtain_mbx_lock_vf(hw);
613 	if (ret_val)
614 		return ret_val;
615 
616 	/* copy the message from the mailbox memory buffer */
617 	for (i = 0; i < size; i++)
618 		msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i);
619 
620 	/* Acknowledge receipt and release mailbox, then we're done */
621 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_ACK);
622 
623 	/* update stats */
624 	IXGBE_EVC_ADD(&hw->mbx.stats.msgs_rx, 1);
625 
626 	return IXGBE_SUCCESS;
627 }
628 
629 /**
630  * ixgbe_read_mbx_vf - Reads a message from the inbox intended for vf
631  * @hw: pointer to the HW structure
632  * @msg: The message buffer
633  * @size: Length of buffer
634  * @mbx_id: id of mailbox to read
635  *
636  * returns SUCCESS if it successfully read message from buffer
637  **/
ixgbe_read_mbx_vf(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 mbx_id)638 static s32 ixgbe_read_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,
639 			     u16 mbx_id)
640 {
641 	u32 vf_mailbox;
642 	s32 ret_val;
643 	u16 i;
644 
645 	DEBUGFUNC("ixgbe_read_mbx_vf");
646 	UNREFERENCED_1PARAMETER(mbx_id);
647 
648 	/* check if there is a message from PF */
649 	ret_val = ixgbe_check_for_msg_vf(hw, 0);
650 	if (ret_val != IXGBE_SUCCESS)
651 		return IXGBE_ERR_MBX_NOMSG;
652 
653 	ixgbe_clear_msg_vf(hw);
654 
655 	/* copy the message from the mailbox memory buffer */
656 	for (i = 0; i < size; i++)
657 		msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i);
658 
659 	/* Acknowledge receipt */
660 	vf_mailbox = ixgbe_read_mailbox_vf(hw);
661 	vf_mailbox |= IXGBE_VFMAILBOX_ACK;
662 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox);
663 
664 	/* update stats */
665 	IXGBE_EVC_ADD(&hw->mbx.stats.msgs_rx, 1);
666 
667 	return IXGBE_SUCCESS;
668 }
669 
670 /**
671  * ixgbe_init_mbx_params_vf - set initial values for vf mailbox
672  * @hw: pointer to the HW structure
673  *
674  * Initializes single set the hw->mbx struct to correct values for vf mailbox
675  * Set of legacy functions is being used here
676  */
ixgbe_init_mbx_params_vf(struct ixgbe_hw * hw)677 void ixgbe_init_mbx_params_vf(struct ixgbe_hw *hw)
678 {
679 	struct ixgbe_mbx_info *mbx = &hw->mbx;
680 
681 	mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT;
682 	mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;
683 
684 	mbx->size = IXGBE_VFMAILBOX_SIZE;
685 
686 	/* VF has only one mailbox connection, no need for more IDs */
687 	mbx->ops[0].release = ixgbe_release_mbx_lock_dummy;
688 	mbx->ops[0].read = ixgbe_read_mbx_vf_legacy;
689 	mbx->ops[0].write = ixgbe_write_mbx_vf_legacy;
690 	mbx->ops[0].check_for_msg = ixgbe_check_for_msg_vf;
691 	mbx->ops[0].check_for_ack = ixgbe_check_for_ack_vf;
692 	mbx->ops[0].check_for_rst = ixgbe_check_for_rst_vf;
693 	mbx->ops[0].clear = NULL;
694 
695 	IXGBE_EVC_STORE(&mbx->stats.msgs_tx, 0);
696 	IXGBE_EVC_STORE(&mbx->stats.msgs_rx, 0);
697 	IXGBE_EVC_STORE(&mbx->stats.reqs, 0);
698 	IXGBE_EVC_STORE(&mbx->stats.acks, 0);
699 	IXGBE_EVC_STORE(&mbx->stats.rsts, 0);
700 }
701 
702 /**
703  * ixgbe_upgrade_mbx_params_vf - set initial values for vf mailbox
704  * @hw: pointer to the HW structure
705  *
706  * Initializes the hw->mbx struct to correct values for vf mailbox
707  */
ixgbe_upgrade_mbx_params_vf(struct ixgbe_hw * hw)708 void ixgbe_upgrade_mbx_params_vf(struct ixgbe_hw *hw)
709 {
710 	struct ixgbe_mbx_info *mbx = &hw->mbx;
711 
712 	mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT;
713 	mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;
714 
715 	mbx->size = IXGBE_VFMAILBOX_SIZE;
716 
717 	/* VF has only one mailbox connection, no need for more IDs */
718 	mbx->ops[0].release = ixgbe_release_mbx_lock_vf;
719 	mbx->ops[0].read = ixgbe_read_mbx_vf;
720 	mbx->ops[0].write = ixgbe_write_mbx_vf;
721 	mbx->ops[0].check_for_msg = ixgbe_check_for_msg_vf;
722 	mbx->ops[0].check_for_ack = ixgbe_check_for_ack_vf;
723 	mbx->ops[0].check_for_rst = ixgbe_check_for_rst_vf;
724 	mbx->ops[0].clear = NULL;
725 }
726 
ixgbe_clear_msg_pf(struct ixgbe_hw * hw,u16 vf_id)727 static void ixgbe_clear_msg_pf(struct ixgbe_hw *hw, u16 vf_id)
728 {
729 	u32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_id);
730 	s32 index = IXGBE_PFMBICR_INDEX(vf_id);
731 	u32 pfmbicr;
732 
733 	pfmbicr = IXGBE_READ_REG(hw, IXGBE_PFMBICR(index));
734 
735 	if (pfmbicr & (IXGBE_PFMBICR_VFREQ_VF1 << vf_shift))
736 		IXGBE_EVC_ADD(&hw->mbx.stats.reqs, 1);
737 
738 	IXGBE_WRITE_REG(hw, IXGBE_PFMBICR(index),
739 			IXGBE_PFMBICR_VFREQ_VF1 << vf_shift);
740 }
741 
ixgbe_clear_ack_pf(struct ixgbe_hw * hw,u16 vf_id)742 static void ixgbe_clear_ack_pf(struct ixgbe_hw *hw, u16 vf_id)
743 {
744 	u32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_id);
745 	s32 index = IXGBE_PFMBICR_INDEX(vf_id);
746 	u32 pfmbicr;
747 
748 	pfmbicr = IXGBE_READ_REG(hw, IXGBE_PFMBICR(index));
749 
750 	if (pfmbicr & (IXGBE_PFMBICR_VFACK_VF1 << vf_shift))
751 		IXGBE_EVC_ADD(&hw->mbx.stats.acks, 1);
752 
753 	IXGBE_WRITE_REG(hw, IXGBE_PFMBICR(index),
754 			IXGBE_PFMBICR_VFACK_VF1 << vf_shift);
755 }
756 
ixgbe_check_for_bit_pf(struct ixgbe_hw * hw,u32 mask,s32 index)757 static s32 ixgbe_check_for_bit_pf(struct ixgbe_hw *hw, u32 mask, s32 index)
758 {
759 	u32 pfmbicr = IXGBE_READ_REG(hw, IXGBE_PFMBICR(index));
760 
761 	if (pfmbicr & mask)
762 		return IXGBE_SUCCESS;
763 
764 	return IXGBE_ERR_MBX;
765 }
766 
767 /**
768  * ixgbe_check_for_msg_pf - checks to see if the VF has sent mail
769  * @hw: pointer to the HW structure
770  * @vf_id: the VF index
771  *
772  * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
773  **/
ixgbe_check_for_msg_pf(struct ixgbe_hw * hw,u16 vf_id)774 static s32 ixgbe_check_for_msg_pf(struct ixgbe_hw *hw, u16 vf_id)
775 {
776 	u32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_id);
777 	s32 index = IXGBE_PFMBICR_INDEX(vf_id);
778 
779 	DEBUGFUNC("ixgbe_check_for_msg_pf");
780 
781 	if (!ixgbe_check_for_bit_pf(hw, IXGBE_PFMBICR_VFREQ_VF1 << vf_shift,
782 				    index))
783 		return IXGBE_SUCCESS;
784 
785 	return IXGBE_ERR_MBX;
786 }
787 
788 /**
789  * ixgbe_check_for_ack_pf - checks to see if the VF has ACKed
790  * @hw: pointer to the HW structure
791  * @vf_id: the VF index
792  *
793  * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
794  **/
ixgbe_check_for_ack_pf(struct ixgbe_hw * hw,u16 vf_id)795 static s32 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_id)
796 {
797 	u32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_id);
798 	s32 index = IXGBE_PFMBICR_INDEX(vf_id);
799 	s32 ret_val = IXGBE_ERR_MBX;
800 
801 	DEBUGFUNC("ixgbe_check_for_ack_pf");
802 
803 	if (!ixgbe_check_for_bit_pf(hw, IXGBE_PFMBICR_VFACK_VF1 << vf_shift,
804 				    index)) {
805 		ret_val = IXGBE_SUCCESS;
806 		/* TODO: should this be autocleared? */
807 		ixgbe_clear_ack_pf(hw, vf_id);
808 	}
809 
810 	return ret_val;
811 }
812 
813 /**
814  * ixgbe_check_for_rst_pf - checks to see if the VF has reset
815  * @hw: pointer to the HW structure
816  * @vf_id: the VF index
817  *
818  * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
819  **/
ixgbe_check_for_rst_pf(struct ixgbe_hw * hw,u16 vf_id)820 static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_id)
821 {
822 	u32 vf_shift = IXGBE_PFVFLRE_SHIFT(vf_id);
823 	u32 index = IXGBE_PFVFLRE_INDEX(vf_id);
824 	s32 ret_val = IXGBE_ERR_MBX;
825 	u32 vflre = 0;
826 
827 	DEBUGFUNC("ixgbe_check_for_rst_pf");
828 
829 	switch (hw->mac.type) {
830 	case ixgbe_mac_82599EB:
831 		vflre = IXGBE_READ_REG(hw, IXGBE_PFVFLRE(index));
832 		break;
833 	case ixgbe_mac_X550:
834 	case ixgbe_mac_X550EM_x:
835 	case ixgbe_mac_X550EM_a:
836 	case ixgbe_mac_X540:
837 		vflre = IXGBE_READ_REG(hw, IXGBE_PFVFLREC(index));
838 		break;
839 	default:
840 		break;
841 	}
842 
843 	if (vflre & (1 << vf_shift)) {
844 		ret_val = IXGBE_SUCCESS;
845 		IXGBE_WRITE_REG(hw, IXGBE_PFVFLREC(index), (1 << vf_shift));
846 		IXGBE_EVC_ADD(&hw->mbx.stats.rsts, 1);
847 	}
848 
849 	return ret_val;
850 }
851 
852 /**
853  * ixgbe_obtain_mbx_lock_pf - obtain mailbox lock
854  * @hw: pointer to the HW structure
855  * @vf_id: the VF index
856  *
857  * return SUCCESS if we obtained the mailbox lock
858  **/
ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw * hw,u16 vf_id)859 static s32 ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_id)
860 {
861 	struct ixgbe_mbx_info *mbx = &hw->mbx;
862 	int countdown = mbx->timeout;
863 	s32 ret_val = IXGBE_ERR_MBX;
864 	u32 pf_mailbox;
865 
866 	DEBUGFUNC("ixgbe_obtain_mbx_lock_pf");
867 
868 	if (!mbx->timeout)
869 		return IXGBE_ERR_CONFIG;
870 
871 	while (countdown--) {
872 		/* Reserve mailbox for PF use */
873 		pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id));
874 		pf_mailbox |= IXGBE_PFMAILBOX_PFU;
875 		IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), pf_mailbox);
876 
877 		/* Verify that PF is the owner of the lock */
878 		pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id));
879 		if (pf_mailbox & IXGBE_PFMAILBOX_PFU) {
880 			ret_val = IXGBE_SUCCESS;
881 			break;
882 		}
883 
884 		/* Wait a bit before trying again */
885 		usec_delay(mbx->usec_delay);
886 	}
887 
888 	if (ret_val != IXGBE_SUCCESS) {
889 		ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
890 			      "Failed to obtain mailbox lock");
891 		ret_val = IXGBE_ERR_TIMEOUT;
892 	}
893 
894 	return ret_val;
895 }
896 
897 /**
898  * ixgbe_release_mbx_lock_pf - release mailbox lock
899  * @hw: pointer to the HW structure
900  * @vf_id: the VF index
901  **/
ixgbe_release_mbx_lock_pf(struct ixgbe_hw * hw,u16 vf_id)902 static void ixgbe_release_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_id)
903 {
904 	u32 pf_mailbox;
905 
906 	DEBUGFUNC("ixgbe_release_mbx_lock_pf");
907 
908 	/* Return ownership of the buffer */
909 	pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id));
910 	pf_mailbox &= ~IXGBE_PFMAILBOX_PFU;
911 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), pf_mailbox);
912 }
913 
914 /**
915  * ixgbe_write_mbx_pf_legacy - Places a message in the mailbox
916  * @hw: pointer to the HW structure
917  * @msg: The message buffer
918  * @size: Length of buffer
919  * @vf_id: the VF index
920  *
921  * returns SUCCESS if it successfully copied message into the buffer
922  **/
ixgbe_write_mbx_pf_legacy(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 vf_id)923 static s32 ixgbe_write_mbx_pf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size,
924 				     u16 vf_id)
925 {
926 	s32 ret_val;
927 	u16 i;
928 
929 	DEBUGFUNC("ixgbe_write_mbx_pf_legacy");
930 
931 	/* lock the mailbox to prevent pf/vf race condition */
932 	ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_id);
933 	if (ret_val)
934 		return ret_val;
935 
936 	/* flush msg and acks as we are overwriting the message buffer */
937 	ixgbe_check_for_msg_pf(hw, vf_id);
938 	ixgbe_clear_msg_pf(hw, vf_id);
939 	ixgbe_check_for_ack_pf(hw, vf_id);
940 	ixgbe_clear_ack_pf(hw, vf_id);
941 
942 	/* copy the caller specified message to the mailbox memory buffer */
943 	for (i = 0; i < size; i++)
944 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i, msg[i]);
945 
946 	/* Interrupt VF to tell it a message has been sent and release buffer*/
947 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), IXGBE_PFMAILBOX_STS);
948 
949 	/* update stats */
950 	IXGBE_EVC_ADD(&hw->mbx.stats.msgs_tx, 1);
951 
952 	return IXGBE_SUCCESS;
953 }
954 
955 /**
956  * ixgbe_write_mbx_pf - Places a message in the mailbox
957  * @hw: pointer to the HW structure
958  * @msg: The message buffer
959  * @size: Length of buffer
960  * @vf_id: the VF index
961  *
962  * returns SUCCESS if it successfully copied message into the buffer
963  **/
ixgbe_write_mbx_pf(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 vf_id)964 static s32 ixgbe_write_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
965 			      u16 vf_id)
966 {
967 	u32 pf_mailbox;
968 	s32 ret_val;
969 	u16 i;
970 
971 	DEBUGFUNC("ixgbe_write_mbx_pf");
972 
973 	/* lock the mailbox to prevent pf/vf race condition */
974 	ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_id);
975 	if (ret_val)
976 		goto out;
977 
978 	/* flush msg and acks as we are overwriting the message buffer */
979 	ixgbe_clear_msg_pf(hw, vf_id);
980 	ixgbe_clear_ack_pf(hw, vf_id);
981 
982 	/* copy the caller specified message to the mailbox memory buffer */
983 	for (i = 0; i < size; i++)
984 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i, msg[i]);
985 
986 	/* Interrupt VF to tell it a message has been sent */
987 	pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id));
988 	pf_mailbox |= IXGBE_PFMAILBOX_STS;
989 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), pf_mailbox);
990 
991 	/* if msg sent wait until we receive an ack */
992 	ixgbe_poll_for_ack(hw, vf_id);
993 
994 	/* update stats */
995 	IXGBE_EVC_ADD(&hw->mbx.stats.msgs_tx, 1);
996 
997 out:
998 	hw->mbx.ops[vf_id].release(hw, vf_id);
999 
1000 	return ret_val;
1001 
1002 }
1003 
1004 /**
1005  * ixgbe_read_mbx_pf_legacy - Read a message from the mailbox
1006  * @hw: pointer to the HW structure
1007  * @msg: The message buffer
1008  * @size: Length of buffer
1009  * @vf_id: the VF index
1010  *
1011  * This function copies a message from the mailbox buffer to the caller's
1012  * memory buffer.  The presumption is that the caller knows that there was
1013  * a message due to a VF request so no polling for message is needed.
1014  **/
ixgbe_read_mbx_pf_legacy(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 vf_id)1015 static s32 ixgbe_read_mbx_pf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size,
1016 				    u16 vf_id)
1017 {
1018 	s32 ret_val;
1019 	u16 i;
1020 
1021 	DEBUGFUNC("ixgbe_read_mbx_pf_legacy");
1022 
1023 	/* lock the mailbox to prevent pf/vf race condition */
1024 	ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_id);
1025 	if (ret_val != IXGBE_SUCCESS)
1026 		return ret_val;
1027 
1028 	/* copy the message to the mailbox memory buffer */
1029 	for (i = 0; i < size; i++)
1030 		msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i);
1031 
1032 	/* Acknowledge the message and release buffer */
1033 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), IXGBE_PFMAILBOX_ACK);
1034 
1035 	/* update stats */
1036 	IXGBE_EVC_ADD(&hw->mbx.stats.msgs_rx, 1);
1037 
1038 	return IXGBE_SUCCESS;
1039 }
1040 
1041 /**
1042  * ixgbe_read_mbx_pf - Read a message from the mailbox
1043  * @hw: pointer to the HW structure
1044  * @msg: The message buffer
1045  * @size: Length of buffer
1046  * @vf_id: the VF index
1047  *
1048  * This function copies a message from the mailbox buffer to the caller's
1049  * memory buffer.  The presumption is that the caller knows that there was
1050  * a message due to a VF request so no polling for message is needed.
1051  **/
ixgbe_read_mbx_pf(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 vf_id)1052 static s32 ixgbe_read_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
1053 			     u16 vf_id)
1054 {
1055 	u32 pf_mailbox;
1056 	s32 ret_val;
1057 	u16 i;
1058 
1059 	DEBUGFUNC("ixgbe_read_mbx_pf");
1060 
1061 	/* check if there is a message from VF */
1062 	ret_val = ixgbe_check_for_msg_pf(hw, vf_id);
1063 	if (ret_val != IXGBE_SUCCESS)
1064 		return IXGBE_ERR_MBX_NOMSG;
1065 
1066 	ixgbe_clear_msg_pf(hw, vf_id);
1067 
1068 	/* copy the message to the mailbox memory buffer */
1069 	for (i = 0; i < size; i++)
1070 		msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i);
1071 
1072 	/* Acknowledge the message and release buffer */
1073 	pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id));
1074 	pf_mailbox |= IXGBE_PFMAILBOX_ACK;
1075 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), pf_mailbox);
1076 
1077 	/* update stats */
1078 	IXGBE_EVC_ADD(&hw->mbx.stats.msgs_rx, 1);
1079 
1080 	return IXGBE_SUCCESS;
1081 }
1082 
1083 /**
1084  * ixgbe_clear_mbx_pf - Clear Mailbox Memory
1085  * @hw: pointer to the HW structure
1086  * @vf_id: the VF index
1087  *
1088  * Set VFMBMEM of given VF to 0x0.
1089  **/
ixgbe_clear_mbx_pf(struct ixgbe_hw * hw,u16 vf_id)1090 static s32 ixgbe_clear_mbx_pf(struct ixgbe_hw *hw, u16 vf_id)
1091 {
1092 	u16 mbx_size = hw->mbx.size;
1093 	u16 i;
1094 
1095 	if (vf_id > 63)
1096 		return IXGBE_ERR_PARAM;
1097 
1098 	for (i = 0; i < mbx_size; ++i)
1099 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i, 0x0);
1100 
1101 	return IXGBE_SUCCESS;
1102 }
1103 
1104 /**
1105  * ixgbe_init_mbx_params_pf_id - set initial values for pf mailbox
1106  * @hw: pointer to the HW structure
1107  * @vf_id: the VF index
1108  *
1109  * Initializes single set of the hw->mbx struct to correct values for pf mailbox
1110  * Set of legacy functions is being used here
1111  */
ixgbe_init_mbx_params_pf_id(struct ixgbe_hw * hw,u16 vf_id)1112 void ixgbe_init_mbx_params_pf_id(struct ixgbe_hw *hw, u16 vf_id)
1113 {
1114 	struct ixgbe_mbx_info *mbx = &hw->mbx;
1115 
1116 	mbx->ops[vf_id].release = ixgbe_release_mbx_lock_dummy;
1117 	mbx->ops[vf_id].read = ixgbe_read_mbx_pf_legacy;
1118 	mbx->ops[vf_id].write = ixgbe_write_mbx_pf_legacy;
1119 	mbx->ops[vf_id].check_for_msg = ixgbe_check_for_msg_pf;
1120 	mbx->ops[vf_id].check_for_ack = ixgbe_check_for_ack_pf;
1121 	mbx->ops[vf_id].check_for_rst = ixgbe_check_for_rst_pf;
1122 	mbx->ops[vf_id].clear = ixgbe_clear_mbx_pf;
1123 }
1124 
1125 /**
1126  * ixgbe_init_mbx_params_pf - set initial values for pf mailbox
1127  * @hw: pointer to the HW structure
1128  *
1129  * Initializes all sets of the hw->mbx struct to correct values for pf
1130  * mailbox. One set corresponds to single VF. It also initializes counters
1131  * and general variables. A set of legacy functions is used by default.
1132  */
ixgbe_init_mbx_params_pf(struct ixgbe_hw * hw)1133 void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw)
1134 {
1135 	u16 i;
1136 	struct ixgbe_mbx_info *mbx = &hw->mbx;
1137 
1138 	/* Ensure we are not calling this function from VF */
1139 	if (hw->mac.type != ixgbe_mac_82599EB &&
1140 	    hw->mac.type != ixgbe_mac_X550 &&
1141 	    hw->mac.type != ixgbe_mac_X550EM_x &&
1142 	    hw->mac.type != ixgbe_mac_X550EM_a &&
1143 	    hw->mac.type != ixgbe_mac_X540)
1144 		return;
1145 
1146 	/* Initialize common mailbox settings */
1147 	mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT;
1148 	mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;
1149 	mbx->size = IXGBE_VFMAILBOX_SIZE;
1150 
1151 	/* Initialize counters with zeroes */
1152 	IXGBE_EVC_STORE(&mbx->stats.msgs_tx, 0);
1153 	IXGBE_EVC_STORE(&mbx->stats.msgs_rx, 0);
1154 	IXGBE_EVC_STORE(&mbx->stats.reqs, 0);
1155 	IXGBE_EVC_STORE(&mbx->stats.acks, 0);
1156 	IXGBE_EVC_STORE(&mbx->stats.rsts, 0);
1157 
1158 	/* No matter of VF number, we initialize params for all 64 VFs. */
1159 	/* TODO: 1. Add a define for max VF and refactor SHARED to get rid
1160 	 * of magic number for that (63 or 64 depending on use case.)
1161 	 * 2. rewrite the code to dynamically allocate mbx->ops[vf_id] for
1162 	 * certain number of VFs instead of default maximum value of 64 (0..63)
1163 	 */
1164 	for (i = 0; i < 64; i++)
1165 		ixgbe_init_mbx_params_pf_id(hw, i);
1166 }
1167 
1168 /**
1169  * ixgbe_upgrade_mbx_params_pf - Upgrade initial values for pf mailbox
1170  * @hw: pointer to the HW structure
1171  * @vf_id: the VF index
1172  *
1173  * Initializes the hw->mbx struct to new function set for improved
1174  * stability and handling of messages.
1175  */
ixgbe_upgrade_mbx_params_pf(struct ixgbe_hw * hw,u16 vf_id)1176 void ixgbe_upgrade_mbx_params_pf(struct ixgbe_hw *hw, u16 vf_id)
1177 {
1178 	struct ixgbe_mbx_info *mbx = &hw->mbx;
1179 
1180    /* Ensure we are not calling this function from VF */
1181 	if (hw->mac.type != ixgbe_mac_82599EB &&
1182 	    hw->mac.type != ixgbe_mac_X550 &&
1183 	    hw->mac.type != ixgbe_mac_X550EM_x &&
1184 	    hw->mac.type != ixgbe_mac_X550EM_a &&
1185 	    hw->mac.type != ixgbe_mac_X540)
1186 		return;
1187 
1188 	mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT;
1189 	mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;
1190 	mbx->size = IXGBE_VFMAILBOX_SIZE;
1191 
1192 	mbx->ops[vf_id].release = ixgbe_release_mbx_lock_pf;
1193 	mbx->ops[vf_id].read = ixgbe_read_mbx_pf;
1194 	mbx->ops[vf_id].write = ixgbe_write_mbx_pf;
1195 	mbx->ops[vf_id].check_for_msg = ixgbe_check_for_msg_pf;
1196 	mbx->ops[vf_id].check_for_ack = ixgbe_check_for_ack_pf;
1197 	mbx->ops[vf_id].check_for_rst = ixgbe_check_for_rst_pf;
1198 	mbx->ops[vf_id].clear = ixgbe_clear_mbx_pf;
1199 }
1200