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