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         ret_val = ixgbe_check_for_msg_vf(hw, 0);
 433         if (ret_val)
 434                 goto out_no_write;
 435         ret_val = ixgbe_check_for_ack_vf(hw, 0);
 436         if (ret_val)
 437                 goto out_no_write;
 438 
 439         /* copy the caller specified message to the mailbox memory buffer */
 440         for (i = 0; i < size; i++)
 441                 IXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFMBMEM, i, msg[i]);
 442 
 443         /* update stats */
 444         hw->mbx.stats.msgs_tx++;
 445 
 446         /* Drop VFU and interrupt the PF to tell it a message has been sent */
 447         IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_REQ);
 448 
 449 out_no_write:
 450         return ret_val;
 451 }
 452 
 453 /**
 454  *  ixgbe_read_mbx_vf - Reads a message from the inbox intended for vf
 455  *  @hw: pointer to the HW structure
 456  *  @msg: The message buffer
 457  *  @size: Length of buffer
 458  *  @mbx_id: id of mailbox to read
 459  *
 460  *  returns SUCCESS if it successfuly read message from buffer
 461  **/
 462 static s32 ixgbe_read_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,
 463                              u16 mbx_id)
 464 {
 465         s32 ret_val = IXGBE_SUCCESS;
 466         u16 i;
 467 
 468         DEBUGFUNC("ixgbe_read_mbx_vf");
 469         UNREFERENCED_1PARAMETER(mbx_id);
 470 
 471         /* lock the mailbox to prevent pf/vf race condition */
 472         ret_val = ixgbe_obtain_mbx_lock_vf(hw);
 473         if (ret_val)
 474                 goto out_no_read;
 475 
 476         /* copy the message from the mailbox memory buffer */
 477         for (i = 0; i < size; i++)
 478                 msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i);
 479 
 480         /* Acknowledge receipt and release mailbox, then we're done */
 481         IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_ACK);
 482 
 483         /* update stats */
 484         hw->mbx.stats.msgs_rx++;
 485 
 486 out_no_read:
 487         return ret_val;
 488 }
 489 
 490 /**
 491  *  ixgbe_init_mbx_params_vf - set initial values for vf mailbox
 492  *  @hw: pointer to the HW structure
 493  *
 494  *  Initializes the hw->mbx struct to correct values for vf mailbox
 495  */
 496 void ixgbe_init_mbx_params_vf(struct ixgbe_hw *hw)
 497 {
 498         struct ixgbe_mbx_info *mbx = &hw->mbx;
 499 
 500         /* start mailbox as timed out and let the reset_hw call set the timeout
 501          * value to begin communications */
 502         mbx->timeout = 0;
 503         mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;
 504 
 505         mbx->size = IXGBE_VFMAILBOX_SIZE;
 506 
 507         mbx->ops.read = ixgbe_read_mbx_vf;
 508         mbx->ops.write = ixgbe_write_mbx_vf;
 509         mbx->ops.read_posted = ixgbe_read_posted_mbx;
 510         mbx->ops.write_posted = ixgbe_write_posted_mbx;
 511         mbx->ops.check_for_msg = ixgbe_check_for_msg_vf;
 512         mbx->ops.check_for_ack = ixgbe_check_for_ack_vf;
 513         mbx->ops.check_for_rst = ixgbe_check_for_rst_vf;
 514 
 515         mbx->stats.msgs_tx = 0;
 516         mbx->stats.msgs_rx = 0;
 517         mbx->stats.reqs = 0;
 518         mbx->stats.acks = 0;
 519         mbx->stats.rsts = 0;
 520 }
 521 
 522 static s32 ixgbe_check_for_bit_pf(struct ixgbe_hw *hw, u32 mask, s32 index)
 523 {
 524         u32 mbvficr = IXGBE_READ_REG(hw, IXGBE_MBVFICR(index));
 525         s32 ret_val = IXGBE_ERR_MBX;
 526 
 527         if (mbvficr & mask) {
 528                 ret_val = IXGBE_SUCCESS;
 529                 IXGBE_WRITE_REG(hw, IXGBE_MBVFICR(index), mask);
 530         }
 531 
 532         return ret_val;
 533 }
 534 
 535 /**
 536  *  ixgbe_check_for_msg_pf - checks to see if the VF has sent mail
 537  *  @hw: pointer to the HW structure
 538  *  @vf_number: the VF index
 539  *
 540  *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
 541  **/
 542 static s32 ixgbe_check_for_msg_pf(struct ixgbe_hw *hw, u16 vf_number)
 543 {
 544         s32 ret_val = IXGBE_ERR_MBX;
 545         s32 index = IXGBE_MBVFICR_INDEX(vf_number);
 546         u32 vf_bit = vf_number % 16;
 547 
 548         DEBUGFUNC("ixgbe_check_for_msg_pf");
 549 
 550         if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFREQ_VF1 << vf_bit,
 551                                     index)) {
 552                 ret_val = IXGBE_SUCCESS;
 553                 hw->mbx.stats.reqs++;
 554         }
 555 
 556         return ret_val;
 557 }
 558 
 559 /**
 560  *  ixgbe_check_for_ack_pf - checks to see if the VF has ACKed
 561  *  @hw: pointer to the HW structure
 562  *  @vf_number: the VF index
 563  *
 564  *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
 565  **/
 566 static s32 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_number)
 567 {
 568         s32 ret_val = IXGBE_ERR_MBX;
 569         s32 index = IXGBE_MBVFICR_INDEX(vf_number);
 570         u32 vf_bit = vf_number % 16;
 571 
 572         DEBUGFUNC("ixgbe_check_for_ack_pf");
 573 
 574         if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFACK_VF1 << vf_bit,
 575                                     index)) {
 576                 ret_val = IXGBE_SUCCESS;
 577                 hw->mbx.stats.acks++;
 578         }
 579 
 580         return ret_val;
 581 }
 582 
 583 /**
 584  *  ixgbe_check_for_rst_pf - checks to see if the VF has reset
 585  *  @hw: pointer to the HW structure
 586  *  @vf_number: the VF index
 587  *
 588  *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
 589  **/
 590 static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_number)
 591 {
 592         u32 reg_offset = (vf_number < 32) ? 0 : 1;
 593         u32 vf_shift = vf_number % 32;
 594         u32 vflre = 0;
 595         s32 ret_val = IXGBE_ERR_MBX;
 596 
 597         DEBUGFUNC("ixgbe_check_for_rst_pf");
 598 
 599         switch (hw->mac.type) {
 600         case ixgbe_mac_82599EB:
 601                 vflre = IXGBE_READ_REG(hw, IXGBE_VFLRE(reg_offset));
 602                 break;
 603         case ixgbe_mac_X540:
 604                 vflre = IXGBE_READ_REG(hw, IXGBE_VFLREC(reg_offset));
 605                 break;
 606         default:
 607                 break;
 608         }
 609 
 610         if (vflre & (1 << vf_shift)) {
 611                 ret_val = IXGBE_SUCCESS;
 612                 IXGBE_WRITE_REG(hw, IXGBE_VFLREC(reg_offset), (1 << vf_shift));
 613                 hw->mbx.stats.rsts++;
 614         }
 615 
 616         return ret_val;
 617 }
 618 
 619 /**
 620  *  ixgbe_obtain_mbx_lock_pf - obtain mailbox lock
 621  *  @hw: pointer to the HW structure
 622  *  @vf_number: the VF index
 623  *
 624  *  return SUCCESS if we obtained the mailbox lock
 625  **/
 626 static s32 ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_number)
 627 {
 628         s32 ret_val = IXGBE_ERR_MBX;
 629         u32 p2v_mailbox;
 630 
 631         DEBUGFUNC("ixgbe_obtain_mbx_lock_pf");
 632 
 633         /* Take ownership of the buffer */
 634         IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_PFU);
 635 
 636         /* reserve mailbox for vf use */
 637         p2v_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_number));
 638         if (p2v_mailbox & IXGBE_PFMAILBOX_PFU)
 639                 ret_val = IXGBE_SUCCESS;
 640 
 641         return ret_val;
 642 }
 643 
 644 /**
 645  *  ixgbe_write_mbx_pf - Places a message in the mailbox
 646  *  @hw: pointer to the HW structure
 647  *  @msg: The message buffer
 648  *  @size: Length of buffer
 649  *  @vf_number: the VF index
 650  *
 651  *  returns SUCCESS if it successfully copied message into the buffer
 652  **/
 653 static s32 ixgbe_write_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
 654                               u16 vf_number)
 655 {
 656         s32 ret_val;
 657         u16 i;
 658 
 659         DEBUGFUNC("ixgbe_write_mbx_pf");
 660 
 661         /* lock the mailbox to prevent pf/vf race condition */
 662         ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number);
 663         if (ret_val)
 664                 goto out_no_write;
 665 
 666         /* flush msg and acks as we are overwriting the message buffer */
 667         ret_val = ixgbe_check_for_msg_vf(hw, 0);
 668         if (ret_val)
 669                 goto out_no_write;
 670         ret_val = ixgbe_check_for_ack_vf(hw, 0);
 671         if (ret_val)
 672                 goto out_no_write;
 673 
 674         /* copy the caller specified message to the mailbox memory buffer */
 675         for (i = 0; i < size; i++)
 676                 IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i, msg[i]);
 677 
 678         /* Interrupt VF to tell it a message has been sent and release buffer*/
 679         IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_STS);
 680 
 681         /* update stats */
 682         hw->mbx.stats.msgs_tx++;
 683 
 684 out_no_write:
 685         return ret_val;
 686 
 687 }
 688 
 689 /**
 690  *  ixgbe_read_mbx_pf - Read a message from the mailbox
 691  *  @hw: pointer to the HW structure
 692  *  @msg: The message buffer
 693  *  @size: Length of buffer
 694  *  @vf_number: the VF index
 695  *
 696  *  This function copies a message from the mailbox buffer to the caller's
 697  *  memory buffer.  The presumption is that the caller knows that there was
 698  *  a message due to a VF request so no polling for message is needed.
 699  **/
 700 static s32 ixgbe_read_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
 701                              u16 vf_number)
 702 {
 703         s32 ret_val;
 704         u16 i;
 705 
 706         DEBUGFUNC("ixgbe_read_mbx_pf");
 707 
 708         /* lock the mailbox to prevent pf/vf race condition */
 709         ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number);
 710         if (ret_val)
 711                 goto out_no_read;
 712 
 713         /* copy the message to the mailbox memory buffer */
 714         for (i = 0; i < size; i++)
 715                 msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i);
 716 
 717         /* Acknowledge the message and release buffer */
 718         IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_ACK);
 719 
 720         /* update stats */
 721         hw->mbx.stats.msgs_rx++;
 722 
 723 out_no_read:
 724         return ret_val;
 725 }
 726 
 727 /**
 728  *  ixgbe_init_mbx_params_pf - set initial values for pf mailbox
 729  *  @hw: pointer to the HW structure
 730  *
 731  *  Initializes the hw->mbx struct to correct values for pf mailbox
 732  */
 733 void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw)
 734 {
 735         struct ixgbe_mbx_info *mbx = &hw->mbx;
 736 
 737         if (hw->mac.type != ixgbe_mac_82599EB &&
 738             hw->mac.type != ixgbe_mac_X540)
 739                 return;
 740 
 741         mbx->timeout = 0;
 742         mbx->usec_delay = 0;
 743 
 744         mbx->size = IXGBE_VFMAILBOX_SIZE;
 745 
 746         mbx->ops.read = ixgbe_read_mbx_pf;
 747         mbx->ops.write = ixgbe_write_mbx_pf;
 748         mbx->ops.read_posted = ixgbe_read_posted_mbx;
 749         mbx->ops.write_posted = ixgbe_write_posted_mbx;
 750         mbx->ops.check_for_msg = ixgbe_check_for_msg_pf;
 751         mbx->ops.check_for_ack = ixgbe_check_for_ack_pf;
 752         mbx->ops.check_for_rst = ixgbe_check_for_rst_pf;
 753 
 754         mbx->stats.msgs_tx = 0;
 755         mbx->stats.msgs_rx = 0;
 756         mbx->stats.reqs = 0;
 757         mbx->stats.acks = 0;
 758         mbx->stats.rsts = 0;
 759 }