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