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