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