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