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