1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2015-2020 Beijing WangXun Technology Co., Ltd. 3 * Copyright(c) 2010-2017 Intel Corporation 4 */ 5 6 #include "txgbe_type.h" 7 8 #include "txgbe_mbx.h" 9 10 /** 11 * txgbe_read_mbx - Reads a message from the mailbox 12 * @hw: pointer to the HW structure 13 * @msg: The message buffer 14 * @size: Length of buffer 15 * @mbx_id: id of mailbox to read 16 * 17 * returns 0 if it successfully read message from buffer 18 **/ 19 s32 txgbe_read_mbx(struct txgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id) 20 { 21 struct txgbe_mbx_info *mbx = &hw->mbx; 22 s32 ret_val = TXGBE_ERR_MBX; 23 24 /* limit read to size of mailbox */ 25 if (size > mbx->size) 26 size = mbx->size; 27 28 if (mbx->read) 29 ret_val = mbx->read(hw, msg, size, mbx_id); 30 31 return ret_val; 32 } 33 34 /** 35 * txgbe_write_mbx - Write a message to the mailbox 36 * @hw: pointer to the HW structure 37 * @msg: The message buffer 38 * @size: Length of buffer 39 * @mbx_id: id of mailbox to write 40 * 41 * returns 0 if it successfully copied message into the buffer 42 **/ 43 s32 txgbe_write_mbx(struct txgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id) 44 { 45 struct txgbe_mbx_info *mbx = &hw->mbx; 46 s32 ret_val = 0; 47 48 if (size > mbx->size) { 49 ret_val = TXGBE_ERR_MBX; 50 DEBUGOUT("Invalid mailbox message size %d", size); 51 } else if (mbx->write) { 52 ret_val = mbx->write(hw, msg, size, mbx_id); 53 } 54 55 return ret_val; 56 } 57 58 /** 59 * txgbe_check_for_msg - checks to see if someone sent us mail 60 * @hw: pointer to the HW structure 61 * @mbx_id: id of mailbox to check 62 * 63 * returns 0 if the Status bit was found or else ERR_MBX 64 **/ 65 s32 txgbe_check_for_msg(struct txgbe_hw *hw, u16 mbx_id) 66 { 67 struct txgbe_mbx_info *mbx = &hw->mbx; 68 s32 ret_val = TXGBE_ERR_MBX; 69 70 if (mbx->check_for_msg) 71 ret_val = mbx->check_for_msg(hw, mbx_id); 72 73 return ret_val; 74 } 75 76 /** 77 * txgbe_check_for_ack - checks to see if someone sent us ACK 78 * @hw: pointer to the HW structure 79 * @mbx_id: id of mailbox to check 80 * 81 * returns 0 if the Status bit was found or else ERR_MBX 82 **/ 83 s32 txgbe_check_for_ack(struct txgbe_hw *hw, u16 mbx_id) 84 { 85 struct txgbe_mbx_info *mbx = &hw->mbx; 86 s32 ret_val = TXGBE_ERR_MBX; 87 88 if (mbx->check_for_ack) 89 ret_val = mbx->check_for_ack(hw, mbx_id); 90 91 return ret_val; 92 } 93 94 /** 95 * txgbe_check_for_rst - checks to see if other side has reset 96 * @hw: pointer to the HW structure 97 * @mbx_id: id of mailbox to check 98 * 99 * returns 0 if the Status bit was found or else ERR_MBX 100 **/ 101 s32 txgbe_check_for_rst(struct txgbe_hw *hw, u16 mbx_id) 102 { 103 struct txgbe_mbx_info *mbx = &hw->mbx; 104 s32 ret_val = TXGBE_ERR_MBX; 105 106 if (mbx->check_for_rst) 107 ret_val = mbx->check_for_rst(hw, mbx_id); 108 109 return ret_val; 110 } 111 112 /** 113 * txgbe_poll_for_msg - Wait for message notification 114 * @hw: pointer to the HW structure 115 * @mbx_id: id of mailbox to write 116 * 117 * returns SUCCESS if it successfully received a message notification 118 **/ 119 STATIC s32 txgbe_poll_for_msg(struct txgbe_hw *hw, u16 mbx_id) 120 { 121 struct txgbe_mbx_info *mbx = &hw->mbx; 122 int countdown = mbx->timeout; 123 124 if (!countdown || !mbx->check_for_msg) 125 goto out; 126 127 while (countdown && mbx->check_for_msg(hw, mbx_id)) { 128 countdown--; 129 if (!countdown) 130 break; 131 usec_delay(mbx->usec_delay); 132 } 133 134 if (countdown == 0) 135 DEBUGOUT("Polling for VF%d mailbox message timedout", mbx_id); 136 137 out: 138 return countdown ? 0 : TXGBE_ERR_MBX; 139 } 140 141 /** 142 * txgbe_poll_for_ack - Wait for message acknowledgment 143 * @hw: pointer to the HW structure 144 * @mbx_id: id of mailbox to write 145 * 146 * returns SUCCESS if it successfully received a message acknowledgment 147 **/ 148 STATIC s32 txgbe_poll_for_ack(struct txgbe_hw *hw, u16 mbx_id) 149 { 150 struct txgbe_mbx_info *mbx = &hw->mbx; 151 int countdown = mbx->timeout; 152 153 if (!countdown || !mbx->check_for_ack) 154 goto out; 155 156 while (countdown && mbx->check_for_ack(hw, mbx_id)) { 157 countdown--; 158 if (!countdown) 159 break; 160 usec_delay(mbx->usec_delay); 161 } 162 163 if (countdown == 0) 164 DEBUGOUT("Polling for VF%d mailbox ack timedout", mbx_id); 165 166 out: 167 return countdown ? 0 : TXGBE_ERR_MBX; 168 } 169 170 /** 171 * txgbe_read_posted_mbx - Wait for message notification and receive message 172 * @hw: pointer to the HW structure 173 * @msg: The message buffer 174 * @size: Length of buffer 175 * @mbx_id: id of mailbox to write 176 * 177 * returns SUCCESS if it successfully received a message notification and 178 * copied it into the receive buffer. 179 **/ 180 s32 txgbe_read_posted_mbx(struct txgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id) 181 { 182 struct txgbe_mbx_info *mbx = &hw->mbx; 183 s32 ret_val = TXGBE_ERR_MBX; 184 185 if (!mbx->read) 186 goto out; 187 188 ret_val = txgbe_poll_for_msg(hw, mbx_id); 189 190 /* if ack received read message, otherwise we timed out */ 191 if (!ret_val) 192 ret_val = mbx->read(hw, msg, size, mbx_id); 193 out: 194 return ret_val; 195 } 196 197 /** 198 * txgbe_write_posted_mbx - Write a message to the mailbox, wait for ack 199 * @hw: pointer to the HW structure 200 * @msg: The message buffer 201 * @size: Length of buffer 202 * @mbx_id: id of mailbox to write 203 * 204 * returns SUCCESS if it successfully copied message into the buffer and 205 * received an ack to that message within delay * timeout period 206 **/ 207 s32 txgbe_write_posted_mbx(struct txgbe_hw *hw, u32 *msg, u16 size, 208 u16 mbx_id) 209 { 210 struct txgbe_mbx_info *mbx = &hw->mbx; 211 s32 ret_val = TXGBE_ERR_MBX; 212 213 /* exit if either we can't write or there isn't a defined timeout */ 214 if (!mbx->write || !mbx->timeout) 215 goto out; 216 217 /* send msg */ 218 ret_val = mbx->write(hw, msg, size, mbx_id); 219 220 /* if msg sent wait until we receive an ack */ 221 if (!ret_val) 222 ret_val = txgbe_poll_for_ack(hw, mbx_id); 223 out: 224 return ret_val; 225 } 226 227 /** 228 * txgbe_read_v2p_mailbox - read v2p mailbox 229 * @hw: pointer to the HW structure 230 * 231 * This function is used to read the v2p mailbox without losing the read to 232 * clear status bits. 233 **/ 234 STATIC u32 txgbe_read_v2p_mailbox(struct txgbe_hw *hw) 235 { 236 u32 v2p_mailbox = rd32(hw, TXGBE_VFMBCTL); 237 238 v2p_mailbox |= hw->mbx.v2p_mailbox; 239 hw->mbx.v2p_mailbox |= v2p_mailbox & TXGBE_VFMBCTL_R2C_BITS; 240 241 return v2p_mailbox; 242 } 243 244 /** 245 * txgbe_check_for_bit_vf - Determine if a status bit was set 246 * @hw: pointer to the HW structure 247 * @mask: bitmask for bits to be tested and cleared 248 * 249 * This function is used to check for the read to clear bits within 250 * the V2P mailbox. 251 **/ 252 STATIC s32 txgbe_check_for_bit_vf(struct txgbe_hw *hw, u32 mask) 253 { 254 u32 v2p_mailbox = txgbe_read_v2p_mailbox(hw); 255 s32 ret_val = TXGBE_ERR_MBX; 256 257 if (v2p_mailbox & mask) 258 ret_val = 0; 259 260 hw->mbx.v2p_mailbox &= ~mask; 261 262 return ret_val; 263 } 264 265 /** 266 * txgbe_check_for_msg_vf - checks to see if the PF has sent mail 267 * @hw: pointer to the HW structure 268 * @mbx_id: id of mailbox to check 269 * 270 * returns SUCCESS if the PF has set the Status bit or else ERR_MBX 271 **/ 272 s32 txgbe_check_for_msg_vf(struct txgbe_hw *hw, u16 mbx_id) 273 { 274 s32 ret_val = TXGBE_ERR_MBX; 275 276 UNREFERENCED_PARAMETER(mbx_id); 277 278 if (!txgbe_check_for_bit_vf(hw, TXGBE_VFMBCTL_PFSTS)) { 279 ret_val = 0; 280 hw->mbx.stats.reqs++; 281 } 282 283 return ret_val; 284 } 285 286 /** 287 * txgbe_check_for_ack_vf - checks to see if the PF has ACK'd 288 * @hw: pointer to the HW structure 289 * @mbx_id: id of mailbox to check 290 * 291 * returns SUCCESS if the PF has set the ACK bit or else ERR_MBX 292 **/ 293 s32 txgbe_check_for_ack_vf(struct txgbe_hw *hw, u16 mbx_id) 294 { 295 s32 ret_val = TXGBE_ERR_MBX; 296 297 UNREFERENCED_PARAMETER(mbx_id); 298 299 if (!txgbe_check_for_bit_vf(hw, TXGBE_VFMBCTL_PFACK)) { 300 ret_val = 0; 301 hw->mbx.stats.acks++; 302 } 303 304 return ret_val; 305 } 306 307 /** 308 * txgbe_check_for_rst_vf - checks to see if the PF has reset 309 * @hw: pointer to the HW structure 310 * @mbx_id: id of mailbox to check 311 * 312 * returns true if the PF has set the reset done bit or else false 313 **/ 314 s32 txgbe_check_for_rst_vf(struct txgbe_hw *hw, u16 mbx_id) 315 { 316 s32 ret_val = TXGBE_ERR_MBX; 317 318 UNREFERENCED_PARAMETER(mbx_id); 319 320 if (!txgbe_check_for_bit_vf(hw, (TXGBE_VFMBCTL_RSTD | 321 TXGBE_VFMBCTL_RSTI))) { 322 ret_val = 0; 323 hw->mbx.stats.rsts++; 324 } 325 326 return ret_val; 327 } 328 329 /** 330 * txgbe_obtain_mbx_lock_vf - obtain mailbox lock 331 * @hw: pointer to the HW structure 332 * 333 * return SUCCESS if we obtained the mailbox lock 334 **/ 335 STATIC s32 txgbe_obtain_mbx_lock_vf(struct txgbe_hw *hw) 336 { 337 s32 ret_val = TXGBE_ERR_MBX; 338 339 /* Take ownership of the buffer */ 340 wr32(hw, TXGBE_VFMBCTL, TXGBE_VFMBCTL_VFU); 341 342 /* reserve mailbox for vf use */ 343 if (txgbe_read_v2p_mailbox(hw) & TXGBE_VFMBCTL_VFU) 344 ret_val = 0; 345 346 return ret_val; 347 } 348 349 /** 350 * txgbe_write_mbx_vf - Write a message to the mailbox 351 * @hw: pointer to the HW structure 352 * @msg: The message buffer 353 * @size: Length of buffer 354 * @mbx_id: id of mailbox to write 355 * 356 * returns SUCCESS if it successfully copied message into the buffer 357 **/ 358 s32 txgbe_write_mbx_vf(struct txgbe_hw *hw, u32 *msg, u16 size, 359 u16 mbx_id) 360 { 361 s32 ret_val; 362 u16 i; 363 364 UNREFERENCED_PARAMETER(mbx_id); 365 366 /* lock the mailbox to prevent pf/vf race condition */ 367 ret_val = txgbe_obtain_mbx_lock_vf(hw); 368 if (ret_val) 369 goto out_no_write; 370 371 /* flush msg and acks as we are overwriting the message buffer */ 372 txgbe_check_for_msg_vf(hw, 0); 373 txgbe_check_for_ack_vf(hw, 0); 374 375 /* copy the caller specified message to the mailbox memory buffer */ 376 for (i = 0; i < size; i++) 377 wr32a(hw, TXGBE_VFMBX, i, msg[i]); 378 379 /* update stats */ 380 hw->mbx.stats.msgs_tx++; 381 382 /* Drop VFU and interrupt the PF to tell it a message has been sent */ 383 wr32(hw, TXGBE_VFMBCTL, TXGBE_VFMBCTL_REQ); 384 385 out_no_write: 386 return ret_val; 387 } 388 389 /** 390 * txgbe_read_mbx_vf - Reads a message from the inbox intended for vf 391 * @hw: pointer to the HW structure 392 * @msg: The message buffer 393 * @size: Length of buffer 394 * @mbx_id: id of mailbox to read 395 * 396 * returns SUCCESS if it successfully read message from buffer 397 **/ 398 s32 txgbe_read_mbx_vf(struct txgbe_hw *hw, u32 *msg, u16 size, 399 u16 mbx_id) 400 { 401 s32 ret_val = 0; 402 u16 i; 403 404 UNREFERENCED_PARAMETER(mbx_id); 405 406 /* lock the mailbox to prevent pf/vf race condition */ 407 ret_val = txgbe_obtain_mbx_lock_vf(hw); 408 if (ret_val) 409 goto out_no_read; 410 411 /* copy the message from the mailbox memory buffer */ 412 for (i = 0; i < size; i++) 413 msg[i] = rd32a(hw, TXGBE_VFMBX, i); 414 415 /* Acknowledge receipt and release mailbox, then we're done */ 416 wr32(hw, TXGBE_VFMBCTL, TXGBE_VFMBCTL_ACK); 417 418 /* update stats */ 419 hw->mbx.stats.msgs_rx++; 420 421 out_no_read: 422 return ret_val; 423 } 424 425 /** 426 * txgbe_init_mbx_params_vf - set initial values for vf mailbox 427 * @hw: pointer to the HW structure 428 * 429 * Initializes the hw->mbx struct to correct values for vf mailbox 430 */ 431 void txgbe_init_mbx_params_vf(struct txgbe_hw *hw) 432 { 433 struct txgbe_mbx_info *mbx = &hw->mbx; 434 435 /* start mailbox as timed out and let the reset_hw call set the timeout 436 * value to begin communications 437 */ 438 mbx->timeout = 0; 439 mbx->usec_delay = TXGBE_VF_MBX_INIT_DELAY; 440 441 mbx->size = TXGBE_P2VMBX_SIZE; 442 443 mbx->stats.msgs_tx = 0; 444 mbx->stats.msgs_rx = 0; 445 mbx->stats.reqs = 0; 446 mbx->stats.acks = 0; 447 mbx->stats.rsts = 0; 448 } 449 450 STATIC s32 txgbe_check_for_bit_pf(struct txgbe_hw *hw, u32 mask, s32 index) 451 { 452 u32 mbvficr = rd32(hw, TXGBE_MBVFICR(index)); 453 s32 ret_val = TXGBE_ERR_MBX; 454 455 if (mbvficr & mask) { 456 ret_val = 0; 457 wr32(hw, TXGBE_MBVFICR(index), mask); 458 } 459 460 return ret_val; 461 } 462 463 /** 464 * txgbe_check_for_msg_pf - checks to see if the VF has sent mail 465 * @hw: pointer to the HW structure 466 * @vf_number: the VF index 467 * 468 * returns 0 if the VF has set the Status bit or else ERR_MBX 469 **/ 470 s32 txgbe_check_for_msg_pf(struct txgbe_hw *hw, u16 vf_number) 471 { 472 s32 ret_val = TXGBE_ERR_MBX; 473 s32 index = TXGBE_MBVFICR_INDEX(vf_number); 474 u32 vf_bit = vf_number % 16; 475 476 if (!txgbe_check_for_bit_pf(hw, TXGBE_MBVFICR_VFREQ_VF1 << vf_bit, 477 index)) { 478 ret_val = 0; 479 hw->mbx.stats.reqs++; 480 } 481 482 return ret_val; 483 } 484 485 /** 486 * txgbe_check_for_ack_pf - checks to see if the VF has ACKed 487 * @hw: pointer to the HW structure 488 * @vf_number: the VF index 489 * 490 * returns 0 if the VF has set the Status bit or else ERR_MBX 491 **/ 492 s32 txgbe_check_for_ack_pf(struct txgbe_hw *hw, u16 vf_number) 493 { 494 s32 ret_val = TXGBE_ERR_MBX; 495 s32 index = TXGBE_MBVFICR_INDEX(vf_number); 496 u32 vf_bit = vf_number % 16; 497 498 if (!txgbe_check_for_bit_pf(hw, TXGBE_MBVFICR_VFACK_VF1 << vf_bit, 499 index)) { 500 ret_val = 0; 501 hw->mbx.stats.acks++; 502 } 503 504 return ret_val; 505 } 506 507 /** 508 * txgbe_check_for_rst_pf - checks to see if the VF has reset 509 * @hw: pointer to the HW structure 510 * @vf_number: the VF index 511 * 512 * returns 0 if the VF has set the Status bit or else ERR_MBX 513 **/ 514 s32 txgbe_check_for_rst_pf(struct txgbe_hw *hw, u16 vf_number) 515 { 516 u32 reg_offset = (vf_number < 32) ? 0 : 1; 517 u32 vf_shift = vf_number % 32; 518 u32 vflre = 0; 519 s32 ret_val = TXGBE_ERR_MBX; 520 521 vflre = rd32(hw, TXGBE_FLRVFE(reg_offset)); 522 if (vflre & (1 << vf_shift)) { 523 ret_val = 0; 524 wr32(hw, TXGBE_FLRVFEC(reg_offset), (1 << vf_shift)); 525 hw->mbx.stats.rsts++; 526 } 527 528 return ret_val; 529 } 530 531 /** 532 * txgbe_obtain_mbx_lock_pf - obtain mailbox lock 533 * @hw: pointer to the HW structure 534 * @vf_number: the VF index 535 * 536 * return 0 if we obtained the mailbox lock 537 **/ 538 STATIC s32 txgbe_obtain_mbx_lock_pf(struct txgbe_hw *hw, u16 vf_number) 539 { 540 s32 ret_val = TXGBE_ERR_MBX; 541 u32 p2v_mailbox; 542 543 /* Take ownership of the buffer */ 544 wr32(hw, TXGBE_MBCTL(vf_number), TXGBE_MBCTL_PFU); 545 546 /* reserve mailbox for vf use */ 547 p2v_mailbox = rd32(hw, TXGBE_MBCTL(vf_number)); 548 if (p2v_mailbox & TXGBE_MBCTL_PFU) 549 ret_val = 0; 550 else 551 DEBUGOUT("Failed to obtain mailbox lock for VF%d", vf_number); 552 553 554 return ret_val; 555 } 556 557 /** 558 * txgbe_write_mbx_pf - Places a message in the mailbox 559 * @hw: pointer to the HW structure 560 * @msg: The message buffer 561 * @size: Length of buffer 562 * @vf_number: the VF index 563 * 564 * returns 0 if it successfully copied message into the buffer 565 **/ 566 s32 txgbe_write_mbx_pf(struct txgbe_hw *hw, u32 *msg, u16 size, u16 vf_number) 567 { 568 s32 ret_val; 569 u16 i; 570 571 /* lock the mailbox to prevent pf/vf race condition */ 572 ret_val = txgbe_obtain_mbx_lock_pf(hw, vf_number); 573 if (ret_val) 574 goto out_no_write; 575 576 /* flush msg and acks as we are overwriting the message buffer */ 577 txgbe_check_for_msg_pf(hw, vf_number); 578 txgbe_check_for_ack_pf(hw, vf_number); 579 580 /* copy the caller specified message to the mailbox memory buffer */ 581 for (i = 0; i < size; i++) 582 wr32a(hw, TXGBE_MBMEM(vf_number), i, msg[i]); 583 584 /* Interrupt VF to tell it a message has been sent and release buffer*/ 585 wr32(hw, TXGBE_MBCTL(vf_number), TXGBE_MBCTL_STS); 586 587 /* update stats */ 588 hw->mbx.stats.msgs_tx++; 589 590 out_no_write: 591 return ret_val; 592 } 593 594 /** 595 * txgbe_read_mbx_pf - Read a message from the mailbox 596 * @hw: pointer to the HW structure 597 * @msg: The message buffer 598 * @size: Length of buffer 599 * @vf_number: the VF index 600 * 601 * This function copies a message from the mailbox buffer to the caller's 602 * memory buffer. The presumption is that the caller knows that there was 603 * a message due to a VF request so no polling for message is needed. 604 **/ 605 s32 txgbe_read_mbx_pf(struct txgbe_hw *hw, u32 *msg, u16 size, u16 vf_number) 606 { 607 s32 ret_val; 608 u16 i; 609 610 /* lock the mailbox to prevent pf/vf race condition */ 611 ret_val = txgbe_obtain_mbx_lock_pf(hw, vf_number); 612 if (ret_val) 613 goto out_no_read; 614 615 /* copy the message to the mailbox memory buffer */ 616 for (i = 0; i < size; i++) 617 msg[i] = rd32a(hw, TXGBE_MBMEM(vf_number), i); 618 619 /* Acknowledge the message and release buffer */ 620 wr32(hw, TXGBE_MBCTL(vf_number), TXGBE_MBCTL_ACK); 621 622 /* update stats */ 623 hw->mbx.stats.msgs_rx++; 624 625 out_no_read: 626 return ret_val; 627 } 628 629 /** 630 * txgbe_init_mbx_params_pf - set initial values for pf mailbox 631 * @hw: pointer to the HW structure 632 * 633 * Initializes the hw->mbx struct to correct values for pf mailbox 634 */ 635 void txgbe_init_mbx_params_pf(struct txgbe_hw *hw) 636 { 637 struct txgbe_mbx_info *mbx = &hw->mbx; 638 639 mbx->timeout = 0; 640 mbx->usec_delay = 0; 641 642 mbx->size = TXGBE_P2VMBX_SIZE; 643 644 mbx->stats.msgs_tx = 0; 645 mbx->stats.msgs_rx = 0; 646 mbx->stats.reqs = 0; 647 mbx->stats.acks = 0; 648 mbx->stats.rsts = 0; 649 } 650