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