]> CyberLeo.Net >> Repos - FreeBSD/releng/8.2.git/blob - sys/dev/ixgbe/ixgbe_mbx.c
MFC ixgbe cummulative patch from stable/8
[FreeBSD/releng/8.2.git] / sys / dev / ixgbe / ixgbe_mbx.c
1 /******************************************************************************
2
3   Copyright (c) 2001-2010, 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  **/
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  **/
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  **/
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  **/
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  **/
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  **/
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  **/
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  **/
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  **/
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  **/
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  **/
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  **/
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  **/
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_PARAMETER(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  **/
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_PARAMETER(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  **/
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_PARAMETER(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  **/
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  **/
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_PARAMETER(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         ixgbe_check_for_msg_vf(hw, 0);
433         ixgbe_check_for_ack_vf(hw, 0);
434
435         /* copy the caller specified message to the mailbox memory buffer */
436         for (i = 0; i < size; i++)
437                 IXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFMBMEM, i, msg[i]);
438
439         /* update stats */
440         hw->mbx.stats.msgs_tx++;
441
442         /* Drop VFU and interrupt the PF to tell it a message has been sent */
443         IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_REQ);
444
445 out_no_write:
446         return ret_val;
447 }
448
449 /**
450  *  ixgbe_read_mbx_vf - Reads a message from the inbox intended for vf
451  *  @hw: pointer to the HW structure
452  *  @msg: The message buffer
453  *  @size: Length of buffer
454  *  @mbx_id: id of mailbox to read
455  *
456  *  returns SUCCESS if it successfuly read message from buffer
457  **/
458 static s32 ixgbe_read_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,
459                              u16 mbx_id)
460 {
461         s32 ret_val = IXGBE_SUCCESS;
462         u16 i;
463
464         DEBUGFUNC("ixgbe_read_mbx_vf");
465         UNREFERENCED_PARAMETER(mbx_id);
466
467         /* lock the mailbox to prevent pf/vf race condition */
468         ret_val = ixgbe_obtain_mbx_lock_vf(hw);
469         if (ret_val)
470                 goto out_no_read;
471
472         /* copy the message from the mailbox memory buffer */
473         for (i = 0; i < size; i++)
474                 msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i);
475
476         /* Acknowledge receipt and release mailbox, then we're done */
477         IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_ACK);
478
479         /* update stats */
480         hw->mbx.stats.msgs_rx++;
481
482 out_no_read:
483         return ret_val;
484 }
485
486 /**
487  *  ixgbe_init_mbx_params_vf - set initial values for vf mailbox
488  *  @hw: pointer to the HW structure
489  *
490  *  Initializes the hw->mbx struct to correct values for vf mailbox
491  */
492 void ixgbe_init_mbx_params_vf(struct ixgbe_hw *hw)
493 {
494         struct ixgbe_mbx_info *mbx = &hw->mbx;
495
496         /* start mailbox as timed out and let the reset_hw call set the timeout
497          * value to begin communications */
498         mbx->timeout = 0;
499         mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;
500
501         mbx->size = IXGBE_VFMAILBOX_SIZE;
502
503         mbx->ops.read = ixgbe_read_mbx_vf;
504         mbx->ops.write = ixgbe_write_mbx_vf;
505         mbx->ops.read_posted = ixgbe_read_posted_mbx;
506         mbx->ops.write_posted = ixgbe_write_posted_mbx;
507         mbx->ops.check_for_msg = ixgbe_check_for_msg_vf;
508         mbx->ops.check_for_ack = ixgbe_check_for_ack_vf;
509         mbx->ops.check_for_rst = ixgbe_check_for_rst_vf;
510
511         mbx->stats.msgs_tx = 0;
512         mbx->stats.msgs_rx = 0;
513         mbx->stats.reqs = 0;
514         mbx->stats.acks = 0;
515         mbx->stats.rsts = 0;
516 }
517
518 static s32 ixgbe_check_for_bit_pf(struct ixgbe_hw *hw, u32 mask, s32 index)
519 {
520         u32 mbvficr = IXGBE_READ_REG(hw, IXGBE_MBVFICR(index));
521         s32 ret_val = IXGBE_ERR_MBX;
522
523         if (mbvficr & mask) {
524                 ret_val = IXGBE_SUCCESS;
525                 IXGBE_WRITE_REG(hw, IXGBE_MBVFICR(index), mask);
526         }
527
528         return ret_val;
529 }
530
531 /**
532  *  ixgbe_check_for_msg_pf - checks to see if the VF has sent mail
533  *  @hw: pointer to the HW structure
534  *  @vf_number: the VF index
535  *
536  *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
537  **/
538 static s32 ixgbe_check_for_msg_pf(struct ixgbe_hw *hw, u16 vf_number)
539 {
540         s32 ret_val = IXGBE_ERR_MBX;
541         s32 index = IXGBE_MBVFICR_INDEX(vf_number);
542         u32 vf_bit = vf_number % 16;
543
544         DEBUGFUNC("ixgbe_check_for_msg_pf");
545
546         if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFREQ_VF1 << vf_bit,
547                                     index)) {
548                 ret_val = IXGBE_SUCCESS;
549                 hw->mbx.stats.reqs++;
550         }
551
552         return ret_val;
553 }
554
555 /**
556  *  ixgbe_check_for_ack_pf - checks to see if the VF has ACKed
557  *  @hw: pointer to the HW structure
558  *  @vf_number: the VF index
559  *
560  *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
561  **/
562 static s32 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_number)
563 {
564         s32 ret_val = IXGBE_ERR_MBX;
565         s32 index = IXGBE_MBVFICR_INDEX(vf_number);
566         u32 vf_bit = vf_number % 16;
567
568         DEBUGFUNC("ixgbe_check_for_ack_pf");
569
570         if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFACK_VF1 << vf_bit,
571                                     index)) {
572                 ret_val = IXGBE_SUCCESS;
573                 hw->mbx.stats.acks++;
574         }
575
576         return ret_val;
577 }
578
579 /**
580  *  ixgbe_check_for_rst_pf - checks to see if the VF has reset
581  *  @hw: pointer to the HW structure
582  *  @vf_number: the VF index
583  *
584  *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
585  **/
586 static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_number)
587 {
588         u32 reg_offset = (vf_number < 32) ? 0 : 1;
589         u32 vf_shift = vf_number % 32;
590         u32 vflre = 0;
591         s32 ret_val = IXGBE_ERR_MBX;
592
593         DEBUGFUNC("ixgbe_check_for_rst_pf");
594
595         switch (hw->mac.type) {
596         case ixgbe_mac_82599EB:
597                 vflre = IXGBE_READ_REG(hw, IXGBE_VFLRE(reg_offset));
598                 break;
599         default:
600                 goto out;
601                 break;
602         }
603
604         if (vflre & (1 << vf_shift)) {
605                 ret_val = IXGBE_SUCCESS;
606                 IXGBE_WRITE_REG(hw, IXGBE_VFLREC(reg_offset), (1 << vf_shift));
607                 hw->mbx.stats.rsts++;
608         }
609
610 out:
611         return ret_val;
612 }
613
614 /**
615  *  ixgbe_obtain_mbx_lock_pf - obtain mailbox lock
616  *  @hw: pointer to the HW structure
617  *  @vf_number: the VF index
618  *
619  *  return SUCCESS if we obtained the mailbox lock
620  **/
621 static s32 ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_number)
622 {
623         s32 ret_val = IXGBE_ERR_MBX;
624         u32 p2v_mailbox;
625
626         DEBUGFUNC("ixgbe_obtain_mbx_lock_pf");
627
628         /* Take ownership of the buffer */
629         IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_PFU);
630
631         /* reserve mailbox for vf use */
632         p2v_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_number));
633         if (p2v_mailbox & IXGBE_PFMAILBOX_PFU)
634                 ret_val = IXGBE_SUCCESS;
635
636         return ret_val;
637 }
638
639 /**
640  *  ixgbe_write_mbx_pf - Places a message in the mailbox
641  *  @hw: pointer to the HW structure
642  *  @msg: The message buffer
643  *  @size: Length of buffer
644  *  @vf_number: the VF index
645  *
646  *  returns SUCCESS if it successfully copied message into the buffer
647  **/
648 static s32 ixgbe_write_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
649                               u16 vf_number)
650 {
651         s32 ret_val;
652         u16 i;
653
654         DEBUGFUNC("ixgbe_write_mbx_pf");
655
656         /* lock the mailbox to prevent pf/vf race condition */
657         ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number);
658         if (ret_val)
659                 goto out_no_write;
660
661         /* flush msg and acks as we are overwriting the message buffer */
662         ixgbe_check_for_msg_pf(hw, vf_number);
663         ixgbe_check_for_ack_pf(hw, vf_number);
664
665         /* copy the caller specified message to the mailbox memory buffer */
666         for (i = 0; i < size; i++)
667                 IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i, msg[i]);
668
669         /* Interrupt VF to tell it a message has been sent and release buffer*/
670         IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_STS);
671
672         /* update stats */
673         hw->mbx.stats.msgs_tx++;
674
675 out_no_write:
676         return ret_val;
677
678 }
679
680 /**
681  *  ixgbe_read_mbx_pf - Read a message from the mailbox
682  *  @hw: pointer to the HW structure
683  *  @msg: The message buffer
684  *  @size: Length of buffer
685  *  @vf_number: the VF index
686  *
687  *  This function copies a message from the mailbox buffer to the caller's
688  *  memory buffer.  The presumption is that the caller knows that there was
689  *  a message due to a VF request so no polling for message is needed.
690  **/
691 static s32 ixgbe_read_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
692                              u16 vf_number)
693 {
694         s32 ret_val;
695         u16 i;
696
697         DEBUGFUNC("ixgbe_read_mbx_pf");
698
699         /* lock the mailbox to prevent pf/vf race condition */
700         ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number);
701         if (ret_val)
702                 goto out_no_read;
703
704         /* copy the message to the mailbox memory buffer */
705         for (i = 0; i < size; i++)
706                 msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i);
707
708         /* Acknowledge the message and release buffer */
709         IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_ACK);
710
711         /* update stats */
712         hw->mbx.stats.msgs_rx++;
713
714 out_no_read:
715         return ret_val;
716 }
717
718 /**
719  *  ixgbe_init_mbx_params_pf - set initial values for pf mailbox
720  *  @hw: pointer to the HW structure
721  *
722  *  Initializes the hw->mbx struct to correct values for pf mailbox
723  */
724 void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw)
725 {
726         struct ixgbe_mbx_info *mbx = &hw->mbx;
727
728         if (hw->mac.type != ixgbe_mac_82599EB)
729                 return;
730
731         mbx->timeout = 0;
732         mbx->usec_delay = 0;
733
734         mbx->size = IXGBE_VFMAILBOX_SIZE;
735
736         mbx->ops.read = ixgbe_read_mbx_pf;
737         mbx->ops.write = ixgbe_write_mbx_pf;
738         mbx->ops.read_posted = ixgbe_read_posted_mbx;
739         mbx->ops.write_posted = ixgbe_write_posted_mbx;
740         mbx->ops.check_for_msg = ixgbe_check_for_msg_pf;
741         mbx->ops.check_for_ack = ixgbe_check_for_ack_pf;
742         mbx->ops.check_for_rst = ixgbe_check_for_rst_pf;
743
744         mbx->stats.msgs_tx = 0;
745         mbx->stats.msgs_rx = 0;
746         mbx->stats.reqs = 0;
747         mbx->stats.acks = 0;
748         mbx->stats.rsts = 0;
749 }
750