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