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