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