linux/drivers/net/ethernet/intel/ixgbevf/mbx.c
<<
>>
Prefs
   1/*******************************************************************************
   2
   3  Intel 82599 Virtual Function driver
   4  Copyright(c) 1999 - 2015 Intel Corporation.
   5
   6  This program is free software; you can redistribute it and/or modify it
   7  under the terms and conditions of the GNU General Public License,
   8  version 2, as published by the Free Software Foundation.
   9
  10  This program is distributed in the hope it will be useful, but WITHOUT
  11  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  13  more details.
  14
  15  You should have received a copy of the GNU General Public License along with
  16  this program; if not, see <http://www.gnu.org/licenses/>.
  17
  18  The full GNU General Public License is included in this distribution in
  19  the file called "COPYING".
  20
  21  Contact Information:
  22  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
  23  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  24
  25*******************************************************************************/
  26
  27#include "mbx.h"
  28#include "ixgbevf.h"
  29
  30/**
  31 *  ixgbevf_poll_for_msg - Wait for message notification
  32 *  @hw: pointer to the HW structure
  33 *
  34 *  returns 0 if it successfully received a message notification
  35 **/
  36static s32 ixgbevf_poll_for_msg(struct ixgbe_hw *hw)
  37{
  38        struct ixgbe_mbx_info *mbx = &hw->mbx;
  39        int countdown = mbx->timeout;
  40
  41        while (countdown && mbx->ops.check_for_msg(hw)) {
  42                countdown--;
  43                udelay(mbx->udelay);
  44        }
  45
  46        /* if we failed, all future posted messages fail until reset */
  47        if (!countdown)
  48                mbx->timeout = 0;
  49
  50        return countdown ? 0 : IXGBE_ERR_MBX;
  51}
  52
  53/**
  54 *  ixgbevf_poll_for_ack - Wait for message acknowledgment
  55 *  @hw: pointer to the HW structure
  56 *
  57 *  returns 0 if it successfully received a message acknowledgment
  58 **/
  59static s32 ixgbevf_poll_for_ack(struct ixgbe_hw *hw)
  60{
  61        struct ixgbe_mbx_info *mbx = &hw->mbx;
  62        int countdown = mbx->timeout;
  63
  64        while (countdown && mbx->ops.check_for_ack(hw)) {
  65                countdown--;
  66                udelay(mbx->udelay);
  67        }
  68
  69        /* if we failed, all future posted messages fail until reset */
  70        if (!countdown)
  71                mbx->timeout = 0;
  72
  73        return countdown ? 0 : IXGBE_ERR_MBX;
  74}
  75
  76/**
  77 *  ixgbevf_read_posted_mbx - Wait for message notification and receive message
  78 *  @hw: pointer to the HW structure
  79 *  @msg: The message buffer
  80 *  @size: Length of buffer
  81 *
  82 *  returns 0 if it successfully received a message notification and
  83 *  copied it into the receive buffer.
  84 **/
  85static s32 ixgbevf_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size)
  86{
  87        struct ixgbe_mbx_info *mbx = &hw->mbx;
  88        s32 ret_val = -IXGBE_ERR_MBX;
  89
  90        if (!mbx->ops.read)
  91                goto out;
  92
  93        ret_val = ixgbevf_poll_for_msg(hw);
  94
  95        /* if ack received read message, otherwise we timed out */
  96        if (!ret_val)
  97                ret_val = mbx->ops.read(hw, msg, size);
  98out:
  99        return ret_val;
 100}
 101
 102/**
 103 *  ixgbevf_write_posted_mbx - Write a message to the mailbox, wait for ack
 104 *  @hw: pointer to the HW structure
 105 *  @msg: The message buffer
 106 *  @size: Length of buffer
 107 *
 108 *  returns 0 if it successfully copied message into the buffer and
 109 *  received an ack to that message within delay * timeout period
 110 **/
 111static s32 ixgbevf_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size)
 112{
 113        struct ixgbe_mbx_info *mbx = &hw->mbx;
 114        s32 ret_val = -IXGBE_ERR_MBX;
 115
 116        /* exit if either we can't write or there isn't a defined timeout */
 117        if (!mbx->ops.write || !mbx->timeout)
 118                goto out;
 119
 120        /* send msg */
 121        ret_val = mbx->ops.write(hw, msg, size);
 122
 123        /* if msg sent wait until we receive an ack */
 124        if (!ret_val)
 125                ret_val = ixgbevf_poll_for_ack(hw);
 126out:
 127        return ret_val;
 128}
 129
 130/**
 131 *  ixgbevf_read_v2p_mailbox - read v2p mailbox
 132 *  @hw: pointer to the HW structure
 133 *
 134 *  This function is used to read the v2p mailbox without losing the read to
 135 *  clear status bits.
 136 **/
 137static u32 ixgbevf_read_v2p_mailbox(struct ixgbe_hw *hw)
 138{
 139        u32 v2p_mailbox = IXGBE_READ_REG(hw, IXGBE_VFMAILBOX);
 140
 141        v2p_mailbox |= hw->mbx.v2p_mailbox;
 142        hw->mbx.v2p_mailbox |= v2p_mailbox & IXGBE_VFMAILBOX_R2C_BITS;
 143
 144        return v2p_mailbox;
 145}
 146
 147/**
 148 *  ixgbevf_check_for_bit_vf - Determine if a status bit was set
 149 *  @hw: pointer to the HW structure
 150 *  @mask: bitmask for bits to be tested and cleared
 151 *
 152 *  This function is used to check for the read to clear bits within
 153 *  the V2P mailbox.
 154 **/
 155static s32 ixgbevf_check_for_bit_vf(struct ixgbe_hw *hw, u32 mask)
 156{
 157        u32 v2p_mailbox = ixgbevf_read_v2p_mailbox(hw);
 158        s32 ret_val = IXGBE_ERR_MBX;
 159
 160        if (v2p_mailbox & mask)
 161                ret_val = 0;
 162
 163        hw->mbx.v2p_mailbox &= ~mask;
 164
 165        return ret_val;
 166}
 167
 168/**
 169 *  ixgbevf_check_for_msg_vf - checks to see if the PF has sent mail
 170 *  @hw: pointer to the HW structure
 171 *
 172 *  returns 0 if the PF has set the Status bit or else ERR_MBX
 173 **/
 174static s32 ixgbevf_check_for_msg_vf(struct ixgbe_hw *hw)
 175{
 176        s32 ret_val = IXGBE_ERR_MBX;
 177
 178        if (!ixgbevf_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFSTS)) {
 179                ret_val = 0;
 180                hw->mbx.stats.reqs++;
 181        }
 182
 183        return ret_val;
 184}
 185
 186/**
 187 *  ixgbevf_check_for_ack_vf - checks to see if the PF has ACK'd
 188 *  @hw: pointer to the HW structure
 189 *
 190 *  returns 0 if the PF has set the ACK bit or else ERR_MBX
 191 **/
 192static s32 ixgbevf_check_for_ack_vf(struct ixgbe_hw *hw)
 193{
 194        s32 ret_val = IXGBE_ERR_MBX;
 195
 196        if (!ixgbevf_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFACK)) {
 197                ret_val = 0;
 198                hw->mbx.stats.acks++;
 199        }
 200
 201        return ret_val;
 202}
 203
 204/**
 205 *  ixgbevf_check_for_rst_vf - checks to see if the PF has reset
 206 *  @hw: pointer to the HW structure
 207 *
 208 *  returns true if the PF has set the reset done bit or else false
 209 **/
 210static s32 ixgbevf_check_for_rst_vf(struct ixgbe_hw *hw)
 211{
 212        s32 ret_val = IXGBE_ERR_MBX;
 213
 214        if (!ixgbevf_check_for_bit_vf(hw, (IXGBE_VFMAILBOX_RSTD |
 215                                           IXGBE_VFMAILBOX_RSTI))) {
 216                ret_val = 0;
 217                hw->mbx.stats.rsts++;
 218        }
 219
 220        return ret_val;
 221}
 222
 223/**
 224 *  ixgbevf_obtain_mbx_lock_vf - obtain mailbox lock
 225 *  @hw: pointer to the HW structure
 226 *
 227 *  return 0 if we obtained the mailbox lock
 228 **/
 229static s32 ixgbevf_obtain_mbx_lock_vf(struct ixgbe_hw *hw)
 230{
 231        s32 ret_val = IXGBE_ERR_MBX;
 232
 233        /* Take ownership of the buffer */
 234        IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_VFU);
 235
 236        /* reserve mailbox for VF use */
 237        if (ixgbevf_read_v2p_mailbox(hw) & IXGBE_VFMAILBOX_VFU)
 238                ret_val = 0;
 239
 240        return ret_val;
 241}
 242
 243/**
 244 *  ixgbevf_write_mbx_vf - Write a message to the mailbox
 245 *  @hw: pointer to the HW structure
 246 *  @msg: The message buffer
 247 *  @size: Length of buffer
 248 *
 249 *  returns 0 if it successfully copied message into the buffer
 250 **/
 251static s32 ixgbevf_write_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size)
 252{
 253        s32 ret_val;
 254        u16 i;
 255
 256        /* lock the mailbox to prevent PF/VF race condition */
 257        ret_val = ixgbevf_obtain_mbx_lock_vf(hw);
 258        if (ret_val)
 259                goto out_no_write;
 260
 261        /* flush msg and acks as we are overwriting the message buffer */
 262        ixgbevf_check_for_msg_vf(hw);
 263        ixgbevf_check_for_ack_vf(hw);
 264
 265        /* copy the caller specified message to the mailbox memory buffer */
 266        for (i = 0; i < size; i++)
 267                IXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFMBMEM, i, msg[i]);
 268
 269        /* update stats */
 270        hw->mbx.stats.msgs_tx++;
 271
 272        /* Drop VFU and interrupt the PF to tell it a message has been sent */
 273        IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_REQ);
 274
 275out_no_write:
 276        return ret_val;
 277}
 278
 279/**
 280 *  ixgbevf_read_mbx_vf - Reads a message from the inbox intended for VF
 281 *  @hw: pointer to the HW structure
 282 *  @msg: The message buffer
 283 *  @size: Length of buffer
 284 *
 285 *  returns 0 if it successfully read message from buffer
 286 **/
 287static s32 ixgbevf_read_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size)
 288{
 289        s32 ret_val = 0;
 290        u16 i;
 291
 292        /* lock the mailbox to prevent PF/VF race condition */
 293        ret_val = ixgbevf_obtain_mbx_lock_vf(hw);
 294        if (ret_val)
 295                goto out_no_read;
 296
 297        /* copy the message from the mailbox memory buffer */
 298        for (i = 0; i < size; i++)
 299                msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i);
 300
 301        /* Acknowledge receipt and release mailbox, then we're done */
 302        IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_ACK);
 303
 304        /* update stats */
 305        hw->mbx.stats.msgs_rx++;
 306
 307out_no_read:
 308        return ret_val;
 309}
 310
 311/**
 312 *  ixgbevf_init_mbx_params_vf - set initial values for VF mailbox
 313 *  @hw: pointer to the HW structure
 314 *
 315 *  Initializes the hw->mbx struct to correct values for VF mailbox
 316 */
 317static s32 ixgbevf_init_mbx_params_vf(struct ixgbe_hw *hw)
 318{
 319        struct ixgbe_mbx_info *mbx = &hw->mbx;
 320
 321        /* start mailbox as timed out and let the reset_hw call set the timeout
 322         * value to begin communications
 323         */
 324        mbx->timeout = 0;
 325        mbx->udelay = IXGBE_VF_MBX_INIT_DELAY;
 326
 327        mbx->size = IXGBE_VFMAILBOX_SIZE;
 328
 329        mbx->stats.msgs_tx = 0;
 330        mbx->stats.msgs_rx = 0;
 331        mbx->stats.reqs = 0;
 332        mbx->stats.acks = 0;
 333        mbx->stats.rsts = 0;
 334
 335        return 0;
 336}
 337
 338const struct ixgbe_mbx_operations ixgbevf_mbx_ops = {
 339        .init_params    = ixgbevf_init_mbx_params_vf,
 340        .read           = ixgbevf_read_mbx_vf,
 341        .write          = ixgbevf_write_mbx_vf,
 342        .read_posted    = ixgbevf_read_posted_mbx,
 343        .write_posted   = ixgbevf_write_posted_mbx,
 344        .check_for_msg  = ixgbevf_check_for_msg_vf,
 345        .check_for_ack  = ixgbevf_check_for_ack_vf,
 346        .check_for_rst  = ixgbevf_check_for_rst_vf,
 347};
 348
 349