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