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