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