xref: /freebsd/sys/dev/ixgbe/ixgbe_mbx.c (revision df02513fd44bcede0aa8833ae5c2af826f63ce10)
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 static s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id);
39 static s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id);
40 
41 /**
42  * ixgbe_read_mbx - Reads a message from the mailbox
43  * @hw: pointer to the HW structure
44  * @msg: The message buffer
45  * @size: Length of buffer
46  * @mbx_id: id of mailbox to read
47  *
48  * returns SUCCESS if it successfully read message from buffer
49  **/
ixgbe_read_mbx(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 mbx_id)50 s32 ixgbe_read_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
51 {
52 	struct ixgbe_mbx_info *mbx = &hw->mbx;
53 
54 	DEBUGFUNC("ixgbe_read_mbx");
55 
56 	/* limit read to size of mailbox */
57 	if (size > mbx->size) {
58 		ERROR_REPORT3(IXGBE_ERROR_ARGUMENT,
59 			      "Invalid mailbox message size %u, changing to %u",
60 			      size, mbx->size);
61 		size = mbx->size;
62 	}
63 
64 	if (mbx->ops[mbx_id].read)
65 		return mbx->ops[mbx_id].read(hw, msg, size, mbx_id);
66 
67 	return IXGBE_ERR_CONFIG;
68 }
69 
70 /**
71  * ixgbe_poll_mbx - Wait for message and read it from the mailbox
72  * @hw: pointer to the HW structure
73  * @msg: The message buffer
74  * @size: Length of buffer
75  * @mbx_id: id of mailbox to read
76  *
77  * returns SUCCESS if it successfully read message from buffer
78  **/
ixgbe_poll_mbx(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 mbx_id)79 s32 ixgbe_poll_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
80 {
81 	struct ixgbe_mbx_info *mbx = &hw->mbx;
82 	s32 ret_val;
83 
84 	DEBUGFUNC("ixgbe_poll_mbx");
85 
86 	if (!mbx->ops[mbx_id].read || !mbx->ops[mbx_id].check_for_msg ||
87 	    !mbx->timeout)
88 		return IXGBE_ERR_CONFIG;
89 
90 	/* limit read to size of mailbox */
91 	if (size > mbx->size) {
92 		ERROR_REPORT3(IXGBE_ERROR_ARGUMENT,
93 			      "Invalid mailbox message size %u, changing to %u",
94 			      size, mbx->size);
95 		size = mbx->size;
96 	}
97 
98 	ret_val = ixgbe_poll_for_msg(hw, mbx_id);
99 	/* if ack received read message, otherwise we timed out */
100 	if (!ret_val)
101 		return mbx->ops[mbx_id].read(hw, msg, size, mbx_id);
102 
103 	return ret_val;
104 }
105 
106 /**
107  * ixgbe_write_mbx - Write a message to the mailbox and wait for ACK
108  * @hw: pointer to the HW structure
109  * @msg: The message buffer
110  * @size: Length of buffer
111  * @mbx_id: id of mailbox to write
112  *
113  * returns SUCCESS if it successfully copied message into the buffer and
114  * received an ACK to that message within specified period
115  *
116  * Note that the caller to this function must lock before calling, since
117  * multiple threads can destroy each other messages.
118  **/
ixgbe_write_mbx(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 mbx_id)119 s32 ixgbe_write_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
120 {
121 	struct ixgbe_mbx_info *mbx = &hw->mbx;
122 	s32 ret_val = IXGBE_ERR_MBX;
123 
124 	DEBUGFUNC("ixgbe_write_mbx");
125 
126 	/*
127 	 * exit if either we can't write, release
128 	 * or there is no timeout defined
129 	 */
130 	if (!mbx->ops[mbx_id].write || !mbx->ops[mbx_id].check_for_ack ||
131 	    !mbx->ops[mbx_id].release || !mbx->timeout)
132 		return IXGBE_ERR_CONFIG;
133 
134 	if (size > mbx->size) {
135 		ret_val = IXGBE_ERR_PARAM;
136 		ERROR_REPORT2(IXGBE_ERROR_ARGUMENT,
137 			     "Invalid mailbox message size %u", size);
138 	} else {
139 		ret_val = mbx->ops[mbx_id].write(hw, msg, size, mbx_id);
140 	}
141 
142 	return ret_val;
143 }
144 
145 /**
146  * ixgbe_check_for_msg - checks to see if someone sent us mail
147  * @hw: pointer to the HW structure
148  * @mbx_id: id of mailbox to check
149  *
150  * returns SUCCESS if the Status bit was found or else ERR_MBX
151  **/
ixgbe_check_for_msg(struct ixgbe_hw * hw,u16 mbx_id)152 s32 ixgbe_check_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
153 {
154 	struct ixgbe_mbx_info *mbx = &hw->mbx;
155 	s32 ret_val = IXGBE_ERR_CONFIG;
156 
157 	DEBUGFUNC("ixgbe_check_for_msg");
158 
159 	if (mbx->ops[mbx_id].check_for_msg)
160 		ret_val = mbx->ops[mbx_id].check_for_msg(hw, mbx_id);
161 
162 	return ret_val;
163 }
164 
165 /**
166  * ixgbe_check_for_ack - checks to see if someone sent us ACK
167  * @hw: pointer to the HW structure
168  * @mbx_id: id of mailbox to check
169  *
170  * returns SUCCESS if the Status bit was found or else ERR_MBX
171  **/
ixgbe_check_for_ack(struct ixgbe_hw * hw,u16 mbx_id)172 s32 ixgbe_check_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
173 {
174 	struct ixgbe_mbx_info *mbx = &hw->mbx;
175 	s32 ret_val = IXGBE_ERR_CONFIG;
176 
177 	DEBUGFUNC("ixgbe_check_for_ack");
178 
179 	if (mbx->ops[mbx_id].check_for_ack)
180 		ret_val = mbx->ops[mbx_id].check_for_ack(hw, mbx_id);
181 
182 	return ret_val;
183 }
184 
185 /**
186  * ixgbe_check_for_rst - checks to see if other side has reset
187  * @hw: pointer to the HW structure
188  * @mbx_id: id of mailbox to check
189  *
190  * returns SUCCESS if the Status bit was found or else ERR_MBX
191  **/
ixgbe_check_for_rst(struct ixgbe_hw * hw,u16 mbx_id)192 s32 ixgbe_check_for_rst(struct ixgbe_hw *hw, u16 mbx_id)
193 {
194 	struct ixgbe_mbx_info *mbx = &hw->mbx;
195 	s32 ret_val = IXGBE_ERR_CONFIG;
196 
197 	DEBUGFUNC("ixgbe_check_for_rst");
198 
199 	if (mbx->ops[mbx_id].check_for_rst)
200 		ret_val = mbx->ops[mbx_id].check_for_rst(hw, mbx_id);
201 
202 	return ret_val;
203 }
204 
205 /**
206  * ixgbe_clear_mbx - Clear Mailbox Memory
207  * @hw: pointer to the HW structure
208  * @mbx_id: id of mailbox to write
209  *
210  * Set VFMBMEM of given VF to 0x0.  A peer-owned or newly posted mailbox is
211  * left intact.
212  **/
ixgbe_clear_mbx(struct ixgbe_hw * hw,u16 mbx_id)213 s32 ixgbe_clear_mbx(struct ixgbe_hw *hw, u16 mbx_id)
214 {
215 	struct ixgbe_mbx_info *mbx = &hw->mbx;
216 	s32 ret_val = IXGBE_ERR_CONFIG;
217 
218 	DEBUGFUNC("ixgbe_clear_mbx");
219 
220 	if (mbx->ops[mbx_id].clear)
221 		ret_val = mbx->ops[mbx_id].clear(hw, mbx_id);
222 
223 	return ret_val;
224 }
225 
226 /**
227  * ixgbe_poll_for_msg - Wait for message notification
228  * @hw: pointer to the HW structure
229  * @mbx_id: id of mailbox to write
230  *
231  * returns SUCCESS if it successfully received a message notification
232  **/
ixgbe_poll_for_msg(struct ixgbe_hw * hw,u16 mbx_id)233 static s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
234 {
235 	struct ixgbe_mbx_info *mbx = &hw->mbx;
236 	int countdown = mbx->timeout;
237 
238 	DEBUGFUNC("ixgbe_poll_for_msg");
239 
240 	if (!countdown || !mbx->ops[mbx_id].check_for_msg)
241 		return IXGBE_ERR_CONFIG;
242 
243 	while (countdown && mbx->ops[mbx_id].check_for_msg(hw, mbx_id)) {
244 		countdown--;
245 		if (!countdown)
246 			break;
247 		usec_delay(mbx->usec_delay);
248 	}
249 
250 	if (countdown == 0) {
251 		ERROR_REPORT2(IXGBE_ERROR_POLLING,
252 			   "Polling for VF%u mailbox message timedout", mbx_id);
253 		return IXGBE_ERR_TIMEOUT;
254 	}
255 
256 	return IXGBE_SUCCESS;
257 }
258 
259 /**
260  * ixgbe_poll_for_ack - Wait for message acknowledgment
261  * @hw: pointer to the HW structure
262  * @mbx_id: id of mailbox to write
263  *
264  * returns SUCCESS if it successfully received a message acknowledgment
265  **/
ixgbe_poll_for_ack(struct ixgbe_hw * hw,u16 mbx_id)266 static s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
267 {
268 	struct ixgbe_mbx_info *mbx = &hw->mbx;
269 	int countdown = mbx->timeout;
270 
271 	DEBUGFUNC("ixgbe_poll_for_ack");
272 
273 	if (!countdown || !mbx->ops[mbx_id].check_for_ack)
274 		return IXGBE_ERR_CONFIG;
275 
276 	while (countdown && mbx->ops[mbx_id].check_for_ack(hw, mbx_id)) {
277 		countdown--;
278 		if (!countdown)
279 			break;
280 		usec_delay(mbx->usec_delay);
281 	}
282 
283 	if (countdown == 0) {
284 		ERROR_REPORT2(IXGBE_ERROR_POLLING,
285 			     "Polling for VF%u mailbox ack timedout", mbx_id);
286 		return IXGBE_ERR_TIMEOUT;
287 	}
288 
289 	return IXGBE_SUCCESS;
290 }
291 
292 /**
293  * ixgbe_read_mailbox_vf - read VF's mailbox register
294  * @hw: pointer to the HW structure
295  *
296  * This function is used to read the mailbox register dedicated for VF without
297  * losing the read to clear status bits.
298  **/
ixgbe_read_mailbox_vf(struct ixgbe_hw * hw)299 static u32 ixgbe_read_mailbox_vf(struct ixgbe_hw *hw)
300 {
301 	u32 vf_mailbox = IXGBE_READ_REG(hw, IXGBE_VFMAILBOX);
302 
303 	vf_mailbox |= hw->mbx.vf_mailbox;
304 	hw->mbx.vf_mailbox |= vf_mailbox & IXGBE_VFMAILBOX_R2C_BITS;
305 
306 	return vf_mailbox;
307 }
308 
ixgbe_clear_msg_vf(struct ixgbe_hw * hw)309 static void ixgbe_clear_msg_vf(struct ixgbe_hw *hw)
310 {
311 	u32 vf_mailbox = ixgbe_read_mailbox_vf(hw);
312 
313 	if (vf_mailbox & IXGBE_VFMAILBOX_PFSTS) {
314 		hw->mbx.stats.reqs++;
315 		hw->mbx.vf_mailbox &= ~IXGBE_VFMAILBOX_PFSTS;
316 	}
317 }
318 
ixgbe_clear_ack_vf(struct ixgbe_hw * hw)319 static void ixgbe_clear_ack_vf(struct ixgbe_hw *hw)
320 {
321 	u32 vf_mailbox = ixgbe_read_mailbox_vf(hw);
322 
323 	if (vf_mailbox & IXGBE_VFMAILBOX_PFACK) {
324 		hw->mbx.stats.acks++;
325 		hw->mbx.vf_mailbox &= ~IXGBE_VFMAILBOX_PFACK;
326 	}
327 }
328 
ixgbe_clear_rst_vf(struct ixgbe_hw * hw)329 static void ixgbe_clear_rst_vf(struct ixgbe_hw *hw)
330 {
331 	u32 vf_mailbox = ixgbe_read_mailbox_vf(hw);
332 
333 	if (vf_mailbox & (IXGBE_VFMAILBOX_RSTI | IXGBE_VFMAILBOX_RSTD)) {
334 		hw->mbx.stats.rsts++;
335 		hw->mbx.vf_mailbox &= ~(IXGBE_VFMAILBOX_RSTI |
336 					IXGBE_VFMAILBOX_RSTD);
337 	}
338 }
339 
340 /**
341  * ixgbe_check_for_bit_vf - Determine if a status bit was set
342  * @hw: pointer to the HW structure
343  * @mask: bitmask for bits to be tested and cleared
344  *
345  * This function is used to check for the read to clear bits within
346  * the V2P mailbox.
347  **/
ixgbe_check_for_bit_vf(struct ixgbe_hw * hw,u32 mask)348 static s32 ixgbe_check_for_bit_vf(struct ixgbe_hw *hw, u32 mask)
349 {
350 	u32 vf_mailbox = ixgbe_read_mailbox_vf(hw);
351 
352 	if (vf_mailbox & mask)
353 		return IXGBE_SUCCESS;
354 
355 	return IXGBE_ERR_MBX;
356 }
357 
358 /**
359  * ixgbe_check_for_msg_vf - checks to see if the PF has sent mail
360  * @hw: pointer to the HW structure
361  * @mbx_id: id of mailbox to check
362  *
363  * returns SUCCESS if the PF has set the Status bit or else ERR_MBX
364  **/
ixgbe_check_for_msg_vf(struct ixgbe_hw * hw,u16 mbx_id)365 static s32 ixgbe_check_for_msg_vf(struct ixgbe_hw *hw, u16 mbx_id)
366 {
367 	UNREFERENCED_1PARAMETER(mbx_id);
368 	DEBUGFUNC("ixgbe_check_for_msg_vf");
369 
370 	if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFSTS))
371 		return IXGBE_SUCCESS;
372 
373 	return IXGBE_ERR_MBX;
374 }
375 
376 /**
377  * ixgbe_check_for_ack_vf - checks to see if the PF has ACK'd
378  * @hw: pointer to the HW structure
379  * @mbx_id: id of mailbox to check
380  *
381  * returns SUCCESS if the PF has set the ACK bit or else ERR_MBX
382  **/
ixgbe_check_for_ack_vf(struct ixgbe_hw * hw,u16 mbx_id)383 static s32 ixgbe_check_for_ack_vf(struct ixgbe_hw *hw, u16 mbx_id)
384 {
385 	UNREFERENCED_1PARAMETER(mbx_id);
386 	DEBUGFUNC("ixgbe_check_for_ack_vf");
387 
388 	if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFACK)) {
389 		/* TODO: should this be autocleared? */
390 		ixgbe_clear_ack_vf(hw);
391 		return IXGBE_SUCCESS;
392 	}
393 
394 	return IXGBE_ERR_MBX;
395 }
396 
397 /**
398  * ixgbe_check_for_rst_vf - checks to see if the PF has reset
399  * @hw: pointer to the HW structure
400  * @mbx_id: id of mailbox to check
401  *
402  * returns true if the PF has set the reset done bit or else false
403  **/
ixgbe_check_for_rst_vf(struct ixgbe_hw * hw,u16 mbx_id)404 static s32 ixgbe_check_for_rst_vf(struct ixgbe_hw *hw, u16 mbx_id)
405 {
406 	UNREFERENCED_1PARAMETER(mbx_id);
407 	DEBUGFUNC("ixgbe_check_for_rst_vf");
408 
409 	if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_RSTI |
410 					  IXGBE_VFMAILBOX_RSTD)) {
411 		/* TODO: should this be autocleared? */
412 		ixgbe_clear_rst_vf(hw);
413 		return IXGBE_SUCCESS;
414 	}
415 
416 	return IXGBE_ERR_MBX;
417 }
418 
419 /**
420  * ixgbe_obtain_mbx_lock_vf - obtain mailbox lock
421  * @hw: pointer to the HW structure
422  *
423  * return SUCCESS if we obtained the mailbox lock
424  **/
ixgbe_obtain_mbx_lock_vf(struct ixgbe_hw * hw)425 static s32 ixgbe_obtain_mbx_lock_vf(struct ixgbe_hw *hw)
426 {
427 	struct ixgbe_mbx_info *mbx = &hw->mbx;
428 	int countdown = mbx->timeout;
429 	s32 ret_val = IXGBE_ERR_MBX;
430 	u32 vf_mailbox;
431 
432 	DEBUGFUNC("ixgbe_obtain_mbx_lock_vf");
433 
434 	if (!mbx->timeout)
435 		return IXGBE_ERR_CONFIG;
436 
437 	while (countdown--) {
438 		/* Reserve mailbox for VF use */
439 		vf_mailbox = ixgbe_read_mailbox_vf(hw);
440 
441 		/* Check if the mailbox is already owned by the VF or PF */
442 		if (vf_mailbox & (IXGBE_VFMAILBOX_VFU | IXGBE_VFMAILBOX_PFU))
443 			goto retry;
444 
445 		vf_mailbox |= IXGBE_VFMAILBOX_VFU;
446 		IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox);
447 
448 		/* Verify that VF is the owner of the lock */
449 		if (ixgbe_read_mailbox_vf(hw) & IXGBE_VFMAILBOX_VFU) {
450 			ret_val = IXGBE_SUCCESS;
451 			break;
452 		}
453 
454 	retry:
455 		/* Wait a bit before trying again */
456 		usec_delay(mbx->usec_delay);
457 	}
458 
459 	if (ret_val != IXGBE_SUCCESS) {
460 		ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
461 				"Failed to obtain mailbox lock");
462 		ret_val = IXGBE_ERR_TIMEOUT;
463 	}
464 
465 	return ret_val;
466 }
467 
468 /**
469  * ixgbe_release_mbx_lock_dummy - release mailbox lock
470  * @hw: pointer to the HW structure
471  * @mbx_id: id of mailbox to read
472  **/
ixgbe_release_mbx_lock_dummy(struct ixgbe_hw * hw,u16 mbx_id)473 static void ixgbe_release_mbx_lock_dummy(struct ixgbe_hw *hw, u16 mbx_id)
474 {
475 	UNREFERENCED_2PARAMETER(hw, mbx_id);
476 
477 	DEBUGFUNC("ixgbe_release_mbx_lock_dummy");
478 }
479 
480 /**
481  * ixgbe_release_mbx_lock_vf - release mailbox lock
482  * @hw: pointer to the HW structure
483  * @mbx_id: id of mailbox to read
484  **/
ixgbe_release_mbx_lock_vf(struct ixgbe_hw * hw,u16 mbx_id)485 static void ixgbe_release_mbx_lock_vf(struct ixgbe_hw *hw, u16 mbx_id)
486 {
487 	u32 vf_mailbox;
488 
489 	UNREFERENCED_1PARAMETER(mbx_id);
490 
491 	DEBUGFUNC("ixgbe_release_mbx_lock_vf");
492 
493 	/* Return ownership of the buffer */
494 	vf_mailbox = ixgbe_read_mailbox_vf(hw);
495 	vf_mailbox &= ~IXGBE_VFMAILBOX_VFU;
496 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox);
497 }
498 
499 /**
500  * ixgbe_write_mbx_vf_legacy - Write a message to the mailbox
501  * @hw: pointer to the HW structure
502  * @msg: The message buffer
503  * @size: Length of buffer
504  * @mbx_id: id of mailbox to write
505  *
506  * returns SUCCESS if it successfully copied message into the buffer
507  **/
ixgbe_write_mbx_vf_legacy(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 mbx_id)508 static s32 ixgbe_write_mbx_vf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size,
509 				     u16 mbx_id)
510 {
511 	s32 ret_val;
512 	u16 i;
513 
514 	UNREFERENCED_1PARAMETER(mbx_id);
515 	DEBUGFUNC("ixgbe_write_mbx_vf_legacy");
516 
517 	/* lock the mailbox to prevent pf/vf race condition */
518 	ret_val = ixgbe_obtain_mbx_lock_vf(hw);
519 	if (ret_val)
520 		return ret_val;
521 
522 	/* flush msg and acks as we are overwriting the message buffer */
523 	ixgbe_check_for_msg_vf(hw, 0);
524 	ixgbe_clear_msg_vf(hw);
525 	ixgbe_check_for_ack_vf(hw, 0);
526 	ixgbe_clear_ack_vf(hw);
527 
528 	/* copy the caller specified message to the mailbox memory buffer */
529 	for (i = 0; i < size; i++)
530 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFMBMEM, i, msg[i]);
531 
532 	/* update stats */
533 	hw->mbx.stats.msgs_tx++;
534 
535 	/* interrupt the PF to tell it a message has been sent */
536 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_REQ);
537 
538 	return IXGBE_SUCCESS;
539 }
540 
541 /**
542  * ixgbe_write_mbx_vf - Write a message to the mailbox
543  * @hw: pointer to the HW structure
544  * @msg: The message buffer
545  * @size: Length of buffer
546  * @mbx_id: id of mailbox to write
547  *
548  * returns SUCCESS if it successfully copied message into the buffer
549  **/
ixgbe_write_mbx_vf(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 mbx_id)550 static s32 ixgbe_write_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,
551 			      u16 mbx_id)
552 {
553 	u32 vf_mailbox;
554 	s32 ret_val;
555 	u16 i;
556 
557 	UNREFERENCED_1PARAMETER(mbx_id);
558 
559 	DEBUGFUNC("ixgbe_write_mbx_vf");
560 
561 	/* lock the mailbox to prevent pf/vf race condition */
562 	ret_val = ixgbe_obtain_mbx_lock_vf(hw);
563 	if (ret_val)
564 		goto out;
565 
566 	/* flush msg and acks as we are overwriting the message buffer */
567 	ixgbe_clear_msg_vf(hw);
568 	ixgbe_clear_ack_vf(hw);
569 
570 	/* copy the caller specified message to the mailbox memory buffer */
571 	for (i = 0; i < size; i++)
572 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFMBMEM, i, msg[i]);
573 
574 	/* update stats */
575 	hw->mbx.stats.msgs_tx++;
576 
577 	/* interrupt the PF to tell it a message has been sent */
578 	vf_mailbox = ixgbe_read_mailbox_vf(hw);
579 	vf_mailbox |= IXGBE_VFMAILBOX_REQ;
580 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox);
581 
582 	/* if msg sent wait until we receive an ack */
583 	ixgbe_poll_for_ack(hw, mbx_id);
584 
585 out:
586 	hw->mbx.ops[mbx_id].release(hw, mbx_id);
587 
588 	return ret_val;
589 }
590 
591 /**
592  * ixgbe_read_mbx_vf_legacy - Reads a message from the inbox intended for vf
593  * @hw: pointer to the HW structure
594  * @msg: The message buffer
595  * @size: Length of buffer
596  * @mbx_id: id of mailbox to read
597  *
598  * returns SUCCESS if it successfully read message from buffer
599  **/
ixgbe_read_mbx_vf_legacy(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 mbx_id)600 static s32 ixgbe_read_mbx_vf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size,
601 				 u16 mbx_id)
602 {
603 	s32 ret_val;
604 	u16 i;
605 
606 	DEBUGFUNC("ixgbe_read_mbx_vf_legacy");
607 	UNREFERENCED_1PARAMETER(mbx_id);
608 
609 	/* lock the mailbox to prevent pf/vf race condition */
610 	ret_val = ixgbe_obtain_mbx_lock_vf(hw);
611 	if (ret_val)
612 		return ret_val;
613 
614 	/* copy the message from the mailbox memory buffer */
615 	for (i = 0; i < size; i++)
616 		msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i);
617 
618 	/* Acknowledge receipt and release mailbox, then we're done */
619 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_ACK);
620 
621 	/* update stats */
622 	hw->mbx.stats.msgs_rx++;
623 
624 	return IXGBE_SUCCESS;
625 }
626 
627 /**
628  * ixgbe_read_mbx_vf - Reads a message from the inbox intended for vf
629  * @hw: pointer to the HW structure
630  * @msg: The message buffer
631  * @size: Length of buffer
632  * @mbx_id: id of mailbox to read
633  *
634  * returns SUCCESS if it successfully read message from buffer
635  **/
ixgbe_read_mbx_vf(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 mbx_id)636 static s32 ixgbe_read_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,
637 			     u16 mbx_id)
638 {
639 	u32 vf_mailbox;
640 	s32 ret_val;
641 	u16 i;
642 
643 	DEBUGFUNC("ixgbe_read_mbx_vf");
644 	UNREFERENCED_1PARAMETER(mbx_id);
645 
646 	/* check if there is a message from PF */
647 	ret_val = ixgbe_check_for_msg_vf(hw, 0);
648 	if (ret_val != IXGBE_SUCCESS)
649 		return IXGBE_ERR_MBX_NOMSG;
650 
651 	ixgbe_clear_msg_vf(hw);
652 
653 	/* copy the message from the mailbox memory buffer */
654 	for (i = 0; i < size; i++)
655 		msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i);
656 
657 	/* Acknowledge receipt */
658 	vf_mailbox = ixgbe_read_mailbox_vf(hw);
659 	vf_mailbox |= IXGBE_VFMAILBOX_ACK;
660 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox);
661 
662 	/* update stats */
663 	hw->mbx.stats.msgs_rx++;
664 
665 	return IXGBE_SUCCESS;
666 }
667 
668 /**
669  * ixgbe_init_mbx_params_vf - set initial values for vf mailbox
670  * @hw: pointer to the HW structure
671  *
672  * Initializes single set the hw->mbx struct to correct values for vf mailbox
673  * Set of legacy functions is being used here
674  */
ixgbe_init_mbx_params_vf(struct ixgbe_hw * hw)675 void ixgbe_init_mbx_params_vf(struct ixgbe_hw *hw)
676 {
677 	struct ixgbe_mbx_info *mbx = &hw->mbx;
678 
679 	mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT;
680 	mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;
681 
682 	mbx->size = IXGBE_VFMAILBOX_SIZE;
683 
684 	/* VF has only one mailbox connection, no need for more IDs */
685 	mbx->ops[0].release = ixgbe_release_mbx_lock_dummy;
686 	mbx->ops[0].read = ixgbe_read_mbx_vf_legacy;
687 	mbx->ops[0].write = ixgbe_write_mbx_vf_legacy;
688 	mbx->ops[0].check_for_msg = ixgbe_check_for_msg_vf;
689 	mbx->ops[0].check_for_ack = ixgbe_check_for_ack_vf;
690 	mbx->ops[0].check_for_rst = ixgbe_check_for_rst_vf;
691 	mbx->ops[0].clear = NULL;
692 
693 	mbx->stats.msgs_tx = 0;
694 	mbx->stats.msgs_rx = 0;
695 	mbx->stats.reqs = 0;
696 	mbx->stats.acks = 0;
697 	mbx->stats.rsts = 0;
698 }
699 
700 /**
701  * ixgbe_upgrade_mbx_params_vf - set initial values for vf mailbox
702  * @hw: pointer to the HW structure
703  *
704  * Initializes the hw->mbx struct to correct values for vf mailbox
705  */
ixgbe_upgrade_mbx_params_vf(struct ixgbe_hw * hw)706 void ixgbe_upgrade_mbx_params_vf(struct ixgbe_hw *hw)
707 {
708 	struct ixgbe_mbx_info *mbx = &hw->mbx;
709 
710 	mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT;
711 	mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;
712 
713 	mbx->size = IXGBE_VFMAILBOX_SIZE;
714 
715 	/* VF has only one mailbox connection, no need for more IDs */
716 	mbx->ops[0].release = ixgbe_release_mbx_lock_vf;
717 	mbx->ops[0].read = ixgbe_read_mbx_vf;
718 	mbx->ops[0].write = ixgbe_write_mbx_vf;
719 	mbx->ops[0].check_for_msg = ixgbe_check_for_msg_vf;
720 	mbx->ops[0].check_for_ack = ixgbe_check_for_ack_vf;
721 	mbx->ops[0].check_for_rst = ixgbe_check_for_rst_vf;
722 	mbx->ops[0].clear = NULL;
723 
724 	mbx->stats.msgs_tx = 0;
725 	mbx->stats.msgs_rx = 0;
726 	mbx->stats.reqs = 0;
727 	mbx->stats.acks = 0;
728 	mbx->stats.rsts = 0;
729 }
730 
ixgbe_clear_msg_pf(struct ixgbe_hw * hw,u16 vf_id)731 static void ixgbe_clear_msg_pf(struct ixgbe_hw *hw, u16 vf_id)
732 {
733 	u32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_id);
734 	s32 index = IXGBE_PFMBICR_INDEX(vf_id);
735 	u32 pfmbicr;
736 
737 	pfmbicr = IXGBE_READ_REG(hw, IXGBE_PFMBICR(index));
738 
739 	if (pfmbicr & (IXGBE_PFMBICR_VFREQ_VF1 << vf_shift))
740 		hw->mbx.stats.reqs++;
741 
742 	IXGBE_WRITE_REG(hw, IXGBE_PFMBICR(index),
743 			IXGBE_PFMBICR_VFREQ_VF1 << vf_shift);
744 }
745 
ixgbe_clear_ack_pf(struct ixgbe_hw * hw,u16 vf_id)746 static void ixgbe_clear_ack_pf(struct ixgbe_hw *hw, u16 vf_id)
747 {
748 	u32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_id);
749 	s32 index = IXGBE_PFMBICR_INDEX(vf_id);
750 	u32 pfmbicr;
751 
752 	pfmbicr = IXGBE_READ_REG(hw, IXGBE_PFMBICR(index));
753 
754 	if (pfmbicr & (IXGBE_PFMBICR_VFACK_VF1 << vf_shift))
755 		hw->mbx.stats.acks++;
756 
757 	IXGBE_WRITE_REG(hw, IXGBE_PFMBICR(index),
758 			IXGBE_PFMBICR_VFACK_VF1 << vf_shift);
759 }
760 
ixgbe_check_for_bit_pf(struct ixgbe_hw * hw,u32 mask,s32 index)761 static s32 ixgbe_check_for_bit_pf(struct ixgbe_hw *hw, u32 mask, s32 index)
762 {
763 	u32 pfmbicr = IXGBE_READ_REG(hw, IXGBE_PFMBICR(index));
764 
765 	if (pfmbicr & mask) {
766 		return IXGBE_SUCCESS;
767 	}
768 
769 	return IXGBE_ERR_MBX;
770 }
771 
772 /**
773  * ixgbe_check_for_msg_pf - checks to see if the VF has sent mail
774  * @hw: pointer to the HW structure
775  * @vf_id: the VF index
776  *
777  * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
778  **/
ixgbe_check_for_msg_pf(struct ixgbe_hw * hw,u16 vf_id)779 static s32 ixgbe_check_for_msg_pf(struct ixgbe_hw *hw, u16 vf_id)
780 {
781 	u32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_id);
782 	s32 index = IXGBE_PFMBICR_INDEX(vf_id);
783 
784 	DEBUGFUNC("ixgbe_check_for_msg_pf");
785 
786 	if (!ixgbe_check_for_bit_pf(hw, IXGBE_PFMBICR_VFREQ_VF1 << vf_shift,
787 				    index))
788 		return IXGBE_SUCCESS;
789 
790 	return IXGBE_ERR_MBX;
791 }
792 
793 /*
794  * Legacy callers expect checking for a message to consume its interrupt
795  * cause before attempting to read the mailbox.  This keeps a failed read
796  * from leaving VFREQ pending indefinitely.
797  */
ixgbe_check_for_msg_pf_legacy(struct ixgbe_hw * hw,u16 vf_id)798 static s32 ixgbe_check_for_msg_pf_legacy(struct ixgbe_hw *hw, u16 vf_id)
799 {
800 	s32 ret_val;
801 
802 	ret_val = ixgbe_check_for_msg_pf(hw, vf_id);
803 	if (ret_val == IXGBE_SUCCESS)
804 		ixgbe_clear_msg_pf(hw, vf_id);
805 
806 	return ret_val;
807 }
808 
809 /**
810  * ixgbe_check_for_ack_pf - checks to see if the VF has ACKed
811  * @hw: pointer to the HW structure
812  * @vf_id: the VF index
813  *
814  * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
815  **/
ixgbe_check_for_ack_pf(struct ixgbe_hw * hw,u16 vf_id)816 static s32 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_id)
817 {
818 	u32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_id);
819 	s32 index = IXGBE_PFMBICR_INDEX(vf_id);
820 	s32 ret_val = IXGBE_ERR_MBX;
821 
822 	DEBUGFUNC("ixgbe_check_for_ack_pf");
823 
824 	if (!ixgbe_check_for_bit_pf(hw, IXGBE_PFMBICR_VFACK_VF1 << vf_shift,
825 				    index)) {
826 		ret_val = IXGBE_SUCCESS;
827 		/* TODO: should this be autocleared? */
828 		ixgbe_clear_ack_pf(hw, vf_id);
829 	}
830 
831 	return ret_val;
832 }
833 
834 /**
835  * ixgbe_check_for_rst_pf - checks to see if the VF has reset
836  * @hw: pointer to the HW structure
837  * @vf_id: the VF index
838  *
839  * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
840  **/
ixgbe_check_for_rst_pf(struct ixgbe_hw * hw,u16 vf_id)841 static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_id)
842 {
843 	u32 vf_shift = IXGBE_PFVFLRE_SHIFT(vf_id);
844 	u32 index = IXGBE_PFVFLRE_INDEX(vf_id);
845 	s32 ret_val = IXGBE_ERR_MBX;
846 	u32 vflre = 0;
847 
848 	DEBUGFUNC("ixgbe_check_for_rst_pf");
849 
850 	switch (hw->mac.type) {
851 	case ixgbe_mac_82599EB:
852 		vflre = IXGBE_READ_REG(hw, IXGBE_PFVFLRE(index));
853 		break;
854 	case ixgbe_mac_X550:
855 	case ixgbe_mac_X550EM_x:
856 	case ixgbe_mac_X550EM_a:
857 	case ixgbe_mac_E610:
858 	case ixgbe_mac_X540:
859 		vflre = IXGBE_READ_REG(hw, IXGBE_PFVFLREC(index));
860 		break;
861 	default:
862 		break;
863 	}
864 
865 	if (vflre & (1U << vf_shift)) {
866 		ret_val = IXGBE_SUCCESS;
867 		IXGBE_WRITE_REG(hw, IXGBE_PFVFLREC(index), 1U << vf_shift);
868 		hw->mbx.stats.rsts++;
869 	}
870 
871 	return ret_val;
872 }
873 
874 /**
875  * ixgbe_obtain_mbx_lock_pf - obtain mailbox lock
876  * @hw: pointer to the HW structure
877  * @vf_id: the VF index
878  *
879  * return SUCCESS if we obtained the mailbox lock
880  **/
ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw * hw,u16 vf_id)881 static s32 ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_id)
882 {
883 	struct ixgbe_mbx_info *mbx = &hw->mbx;
884 	int countdown = mbx->timeout;
885 	s32 ret_val = IXGBE_ERR_MBX;
886 	u32 pf_mailbox;
887 
888 	DEBUGFUNC("ixgbe_obtain_mbx_lock_pf");
889 
890 	if (!mbx->timeout)
891 		return IXGBE_ERR_CONFIG;
892 
893 	while (countdown--) {
894 		/* Reserve mailbox for PF use */
895 		pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id));
896 
897 		/* A peer-held mailbox cannot be recovered by retrying here. */
898 		if (pf_mailbox & IXGBE_PFMAILBOX_VFU)
899 			return IXGBE_ERR_MBX;
900 
901 		/* Retry transient contention with another PF-side caller. */
902 		if (pf_mailbox & IXGBE_PFMAILBOX_PFU)
903 			goto retry;
904 
905 		pf_mailbox |= IXGBE_PFMAILBOX_PFU;
906 		IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), pf_mailbox);
907 
908 		/* Verify that PF is the owner of the lock */
909 		pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id));
910 		if (pf_mailbox & IXGBE_PFMAILBOX_PFU) {
911 			ret_val = IXGBE_SUCCESS;
912 			break;
913 		}
914 
915 	retry:
916 		/* Wait a bit before trying again */
917 		usec_delay(mbx->usec_delay);
918 	}
919 
920 	if (ret_val != IXGBE_SUCCESS) {
921 		ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
922 			      "Failed to obtain mailbox lock");
923 		ret_val = IXGBE_ERR_TIMEOUT;
924 	}
925 
926 	return ret_val;
927 }
928 
929 /**
930  * ixgbe_release_mbx_lock_pf - release mailbox lock
931  * @hw: pointer to the HW structure
932  * @vf_id: the VF index
933  **/
ixgbe_release_mbx_lock_pf(struct ixgbe_hw * hw,u16 vf_id)934 static void ixgbe_release_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_id)
935 {
936 	u32 pf_mailbox;
937 
938 	DEBUGFUNC("ixgbe_release_mbx_lock_pf");
939 
940 	/* Return ownership of the buffer */
941 	pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id));
942 	pf_mailbox &= ~IXGBE_PFMAILBOX_PFU;
943 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), pf_mailbox);
944 }
945 
946 /**
947  * ixgbe_write_mbx_pf_legacy - Places a message in the mailbox
948  * @hw: pointer to the HW structure
949  * @msg: The message buffer
950  * @size: Length of buffer
951  * @vf_id: the VF index
952  *
953  * returns SUCCESS if it successfully copied message into the buffer
954  **/
ixgbe_write_mbx_pf_legacy(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 vf_id)955 static s32 ixgbe_write_mbx_pf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size,
956 				     u16 vf_id)
957 {
958 	s32 ret_val;
959 	u16 i;
960 
961 	DEBUGFUNC("ixgbe_write_mbx_pf_legacy");
962 
963 	/* lock the mailbox to prevent pf/vf race condition */
964 	ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_id);
965 	if (ret_val)
966 		return ret_val;
967 
968 	/*
969 	 * A VF request wins over an asynchronous PF message.  Recheck VFREQ
970 	 * after acquiring PFU so the request and its payload remain intact for
971 	 * the normal mailbox path.
972 	 */
973 	if (ixgbe_check_for_msg_pf(hw, vf_id) == IXGBE_SUCCESS) {
974 		ixgbe_release_mbx_lock_pf(hw, vf_id);
975 		return IXGBE_ERR_MBX;
976 	}
977 
978 	/* flush msg and acks as we are overwriting the message buffer */
979 	ixgbe_clear_msg_pf(hw, vf_id);
980 	ixgbe_check_for_ack_pf(hw, vf_id);
981 	ixgbe_clear_ack_pf(hw, vf_id);
982 
983 	/* copy the caller specified message to the mailbox memory buffer */
984 	for (i = 0; i < size; i++)
985 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i, msg[i]);
986 
987 	/* Interrupt VF to tell it a message has been sent and release buffer*/
988 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), IXGBE_PFMAILBOX_STS);
989 
990 	/* update stats */
991 	hw->mbx.stats.msgs_tx++;
992 
993 	return IXGBE_SUCCESS;
994 }
995 
996 /**
997  * ixgbe_write_mbx_pf - Places a message in the mailbox
998  * @hw: pointer to the HW structure
999  * @msg: The message buffer
1000  * @size: Length of buffer
1001  * @vf_id: the VF index
1002  *
1003  * returns SUCCESS if it successfully copied message into the buffer
1004  **/
ixgbe_write_mbx_pf(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 vf_id)1005 static s32 ixgbe_write_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
1006 			      u16 vf_id)
1007 {
1008 	u32 pf_mailbox;
1009 	s32 ret_val;
1010 	u16 i;
1011 
1012 	DEBUGFUNC("ixgbe_write_mbx_pf");
1013 
1014 	/* lock the mailbox to prevent pf/vf race condition */
1015 	ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_id);
1016 	if (ret_val)
1017 		goto out;
1018 
1019 	/*
1020 	 * A VF request wins over an asynchronous PF message.  PFU now keeps
1021 	 * PFMBMEM stable, so recheck VFREQ under ownership and leave the request
1022 	 * intact for the normal mailbox path to consume.
1023 	 */
1024 	if (ixgbe_check_for_msg_pf(hw, vf_id) == IXGBE_SUCCESS) {
1025 		ret_val = IXGBE_ERR_MBX;
1026 		goto out;
1027 	}
1028 
1029 	/* flush msg and acks as we are overwriting the message buffer */
1030 	ixgbe_clear_msg_pf(hw, vf_id);
1031 	ixgbe_clear_ack_pf(hw, vf_id);
1032 
1033 	/* copy the caller specified message to the mailbox memory buffer */
1034 	for (i = 0; i < size; i++)
1035 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i, msg[i]);
1036 
1037 	/* interrupt VF to tell it a message has been sent */
1038 	pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id));
1039 	pf_mailbox |= IXGBE_PFMAILBOX_STS;
1040 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), pf_mailbox);
1041 
1042 	/* if msg sent wait until we receive an ack */
1043 	if (msg[0] & IXGBE_VT_MSGTYPE_CTS)
1044 		ixgbe_poll_for_ack(hw, vf_id);
1045 
1046 	/* update stats */
1047 	hw->mbx.stats.msgs_tx++;
1048 
1049 out:
1050 	hw->mbx.ops[vf_id].release(hw, vf_id);
1051 
1052 	return ret_val;
1053 
1054 }
1055 
1056 /**
1057  * ixgbe_read_mbx_pf_legacy - Read a message from the mailbox
1058  * @hw: pointer to the HW structure
1059  * @msg: The message buffer
1060  * @size: Length of buffer
1061  * @vf_id: the VF index
1062  *
1063  * This function copies a message from the mailbox buffer to the caller's
1064  * memory buffer.  The presumption is that the caller knows that there was
1065  * a message due to a VF request so no polling for message is needed.
1066  **/
ixgbe_read_mbx_pf_legacy(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 vf_id)1067 static s32 ixgbe_read_mbx_pf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size,
1068 				    u16 vf_id)
1069 {
1070 	s32 ret_val;
1071 	u16 i;
1072 
1073 	DEBUGFUNC("ixgbe_read_mbx_pf_legacy");
1074 
1075 	/* lock the mailbox to prevent pf/vf race condition */
1076 	ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_id);
1077 	if (ret_val != IXGBE_SUCCESS)
1078 		return ret_val;
1079 
1080 	/* copy the message to the mailbox memory buffer */
1081 	for (i = 0; i < size; i++)
1082 		msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i);
1083 
1084 	/* Acknowledge the message and release buffer */
1085 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), IXGBE_PFMAILBOX_ACK);
1086 
1087 	/* update stats */
1088 	hw->mbx.stats.msgs_rx++;
1089 
1090 	return IXGBE_SUCCESS;
1091 }
1092 
1093 /**
1094  * ixgbe_read_mbx_pf - Read a message from the mailbox
1095  * @hw: pointer to the HW structure
1096  * @msg: The message buffer
1097  * @size: Length of buffer
1098  * @vf_id: the VF index
1099  *
1100  * This function copies a message from the mailbox buffer to the caller's
1101  * memory buffer.  The presumption is that the caller knows that there was
1102  * a message due to a VF request so no polling for message is needed.
1103  **/
ixgbe_read_mbx_pf(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 vf_id)1104 static s32 ixgbe_read_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
1105 			     u16 vf_id)
1106 {
1107 	u32 pf_mailbox;
1108 	s32 ret_val;
1109 	u16 i;
1110 
1111 	DEBUGFUNC("ixgbe_read_mbx_pf");
1112 
1113 	/* check if there is a message from VF */
1114 	ret_val = ixgbe_check_for_msg_pf(hw, vf_id);
1115 	if (ret_val != IXGBE_SUCCESS)
1116 		return IXGBE_ERR_MBX_NOMSG;
1117 
1118 	ixgbe_clear_msg_pf(hw, vf_id);
1119 
1120 	/* copy the message to the mailbox memory buffer */
1121 	for (i = 0; i < size; i++)
1122 		msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i);
1123 
1124 	/* Acknowledge the message and release buffer */
1125 	pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id));
1126 	pf_mailbox |= IXGBE_PFMAILBOX_ACK;
1127 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), pf_mailbox);
1128 
1129 	/* update stats */
1130 	hw->mbx.stats.msgs_rx++;
1131 
1132 	return IXGBE_SUCCESS;
1133 }
1134 
1135 /**
1136  * ixgbe_clear_mbx_pf - Clear idle Mailbox Memory
1137  * @hw: pointer to the HW structure
1138  * @vf_id: the VF index
1139  *
1140  * Set VFMBMEM of given VF to 0x0 unless the VF owns it or has posted a new
1141  * request.
1142  **/
ixgbe_clear_mbx_pf(struct ixgbe_hw * hw,u16 vf_id)1143 static s32 ixgbe_clear_mbx_pf(struct ixgbe_hw *hw, u16 vf_id)
1144 {
1145 	s32 ret_val;
1146 	u16 mbx_size;
1147 	u16 i;
1148 
1149 	if (vf_id > 63)
1150 		return IXGBE_ERR_PARAM;
1151 
1152 	/*
1153 	 * Serialize against a VF composing a request.  After acquiring PFU,
1154 	 * recheck VFREQ to close the window between the caller's mailbox check
1155 	 * and this clear.  Leave a newly posted request intact for the normal
1156 	 * mailbox path to consume.
1157 	 */
1158 	ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_id);
1159 	if (ret_val != IXGBE_SUCCESS)
1160 		return ret_val;
1161 	if (ixgbe_check_for_msg_pf(hw, vf_id) == IXGBE_SUCCESS) {
1162 		ret_val = IXGBE_ERR_MBX;
1163 		goto out;
1164 	}
1165 
1166 	mbx_size = hw->mbx.size;
1167 	for (i = 0; i < mbx_size; ++i)
1168 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i, 0x0);
1169 	ret_val = IXGBE_SUCCESS;
1170 
1171 out:
1172 	ixgbe_release_mbx_lock_pf(hw, vf_id);
1173 	return ret_val;
1174 }
1175 
1176 /**
1177  * ixgbe_force_clear_mbx_pf - Revoke stale VF ownership and clear its mailbox
1178  * @hw: pointer to the HW structure
1179  * @vf_id: the VF index
1180  *
1181  * VFLR does not clear VFMAILBOX.VFU on some devices.  The caller must allow a
1182  * live VF a bounded interval to finish posting its reset request before using
1183  * this function.  Refuse to revoke ownership if a request is already posted,
1184  * then use RVFU and the normal synchronized clear path.
1185  **/
ixgbe_force_clear_mbx_pf(struct ixgbe_hw * hw,u16 vf_id)1186 s32 ixgbe_force_clear_mbx_pf(struct ixgbe_hw *hw, u16 vf_id)
1187 {
1188 	u32 pf_mailbox;
1189 
1190 	if (vf_id > 63)
1191 		return IXGBE_ERR_PARAM;
1192 
1193 	pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id));
1194 	if ((pf_mailbox & IXGBE_PFMAILBOX_VFU) == 0)
1195 		return ixgbe_clear_mbx_pf(hw, vf_id);
1196 	if (ixgbe_check_for_msg_pf(hw, vf_id) == IXGBE_SUCCESS)
1197 		return IXGBE_ERR_MBX;
1198 
1199 	/*
1200 	 * Hardware has no atomic revoke-if-idle operation.  A VF that starts a
1201 	 * request after the grace interval can race RVFU; the synchronized clear
1202 	 * below detects a request that has reached VFREQ, and its failure makes
1203 	 * the caller retain cleanup state for another interval.
1204 	 */
1205 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), IXGBE_PFMAILBOX_RVFU);
1206 	IXGBE_WRITE_FLUSH(hw);
1207 
1208 	return ixgbe_clear_mbx_pf(hw, vf_id);
1209 }
1210 
1211 /**
1212  * ixgbe_init_mbx_params_pf_id - set initial values for pf mailbox
1213  * @hw: pointer to the HW structure
1214  * @vf_id: the VF index
1215  *
1216  * Initializes single set of the hw->mbx struct to correct values for pf mailbox
1217  * Set of legacy functions is being used here
1218  */
ixgbe_init_mbx_params_pf_id(struct ixgbe_hw * hw,u16 vf_id)1219 void ixgbe_init_mbx_params_pf_id(struct ixgbe_hw *hw, u16 vf_id)
1220 {
1221 	struct ixgbe_mbx_info *mbx = &hw->mbx;
1222 
1223 	mbx->ops[vf_id].release = ixgbe_release_mbx_lock_dummy;
1224 	mbx->ops[vf_id].read = ixgbe_read_mbx_pf_legacy;
1225 	mbx->ops[vf_id].write = ixgbe_write_mbx_pf_legacy;
1226 	mbx->ops[vf_id].check_for_msg = ixgbe_check_for_msg_pf_legacy;
1227 	mbx->ops[vf_id].check_for_ack = ixgbe_check_for_ack_pf;
1228 	mbx->ops[vf_id].check_for_rst = ixgbe_check_for_rst_pf;
1229 	mbx->ops[vf_id].clear = ixgbe_clear_mbx_pf;
1230 }
1231 
1232 /**
1233  * ixgbe_init_mbx_params_pf - set initial values for pf mailbox
1234  * @hw: pointer to the HW structure
1235  *
1236  * Initializes all sets of the hw->mbx struct to correct values for pf
1237  * mailbox. One set corresponds to single VF. It also initializes counters
1238  * and general variables. A set of legacy functions is used by default.
1239  */
ixgbe_init_mbx_params_pf(struct ixgbe_hw * hw)1240 void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw)
1241 {
1242 	u16 i;
1243 	struct ixgbe_mbx_info *mbx = &hw->mbx;
1244 
1245 	/* Ensure we are not calling this function from VF */
1246 	if (hw->mac.type != ixgbe_mac_82599EB &&
1247 	    hw->mac.type != ixgbe_mac_X550 &&
1248 	    hw->mac.type != ixgbe_mac_X550EM_x &&
1249 	    hw->mac.type != ixgbe_mac_X550EM_a &&
1250 	    hw->mac.type != ixgbe_mac_E610 &&
1251 	    hw->mac.type != ixgbe_mac_X540)
1252 		return;
1253 
1254 	/* Initialize common mailbox settings */
1255 	mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT;
1256 	mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;
1257 	mbx->size = IXGBE_VFMAILBOX_SIZE;
1258 
1259 	/* Initialize counters with zeroes */
1260 	mbx->stats.msgs_tx = 0;
1261 	mbx->stats.msgs_rx = 0;
1262 	mbx->stats.reqs = 0;
1263 	mbx->stats.acks = 0;
1264 	mbx->stats.rsts = 0;
1265 
1266 	/* No matter of VF number, we initialize params for all 64 VFs. */
1267 	/* TODO: 1. Add a define for max VF and refactor SHARED to get rid
1268 	 * of magic number for that (63 or 64 depending on use case.)
1269 	 * 2. rewrite the code to dynamically allocate mbx->ops[vf_id] for
1270 	 * certain number of VFs instead of default maximum value of 64 (0..63)
1271 	 */
1272 	for (i = 0; i < 64; i++)
1273 		ixgbe_init_mbx_params_pf_id(hw, i);
1274 }
1275 
1276 /**
1277  * ixgbe_upgrade_mbx_params_pf - Upgrade initial values for pf mailbox
1278  * @hw: pointer to the HW structure
1279  * @vf_id: the VF index
1280  *
1281  * Initializes the hw->mbx struct to new function set for improved
1282  * stability and handling of messages.
1283  */
ixgbe_upgrade_mbx_params_pf(struct ixgbe_hw * hw,u16 vf_id)1284 void ixgbe_upgrade_mbx_params_pf(struct ixgbe_hw *hw, u16 vf_id)
1285 {
1286 	struct ixgbe_mbx_info *mbx = &hw->mbx;
1287 
1288 	/* Ensure we are not calling this function from VF */
1289 	if (hw->mac.type != ixgbe_mac_82599EB &&
1290 	    hw->mac.type != ixgbe_mac_X550 &&
1291 	    hw->mac.type != ixgbe_mac_X550EM_x &&
1292 	    hw->mac.type != ixgbe_mac_X550EM_a &&
1293 	    hw->mac.type != ixgbe_mac_E610 &&
1294 	    hw->mac.type != ixgbe_mac_X540)
1295 		return;
1296 
1297 	mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT;
1298 	mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;
1299 	mbx->size = IXGBE_VFMAILBOX_SIZE;
1300 
1301 	mbx->ops[vf_id].release = ixgbe_release_mbx_lock_pf;
1302 	mbx->ops[vf_id].read = ixgbe_read_mbx_pf;
1303 	mbx->ops[vf_id].write = ixgbe_write_mbx_pf;
1304 	mbx->ops[vf_id].check_for_msg = ixgbe_check_for_msg_pf;
1305 	mbx->ops[vf_id].check_for_ack = ixgbe_check_for_ack_pf;
1306 	mbx->ops[vf_id].check_for_rst = ixgbe_check_for_rst_pf;
1307 	mbx->ops[vf_id].clear = ixgbe_clear_mbx_pf;
1308 
1309 	mbx->stats.msgs_tx = 0;
1310 	mbx->stats.msgs_rx = 0;
1311 	mbx->stats.reqs = 0;
1312 	mbx->stats.acks = 0;
1313 	mbx->stats.rsts = 0;
1314 }
1315