linux/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.c
<<
>>
Prefs
   1/*******************************************************************************
   2
   3  Intel 10 Gigabit PCI Express Linux driver
   4  Copyright(c) 1999 - 2013 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, write to the Free Software Foundation, Inc.,
  17  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  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 <linux/pci.h>
  29#include <linux/delay.h>
  30#include "ixgbe_type.h"
  31#include "ixgbe_common.h"
  32#include "ixgbe_mbx.h"
  33
  34/**
  35 *  ixgbe_read_mbx - Reads a message from 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 read
  40 *
  41 *  returns SUCCESS if it successfully read message from buffer
  42 **/
  43s32 ixgbe_read_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
  44{
  45        struct ixgbe_mbx_info *mbx = &hw->mbx;
  46        s32 ret_val = IXGBE_ERR_MBX;
  47
  48        /* limit read to size of mailbox */
  49        if (size > mbx->size)
  50                size = mbx->size;
  51
  52        if (mbx->ops.read)
  53                ret_val = mbx->ops.read(hw, msg, size, mbx_id);
  54
  55        return ret_val;
  56}
  57
  58/**
  59 *  ixgbe_write_mbx - Write a message to the mailbox
  60 *  @hw: pointer to the HW structure
  61 *  @msg: The message buffer
  62 *  @size: Length of buffer
  63 *  @mbx_id: id of mailbox to write
  64 *
  65 *  returns SUCCESS if it successfully copied message into the buffer
  66 **/
  67s32 ixgbe_write_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
  68{
  69        struct ixgbe_mbx_info *mbx = &hw->mbx;
  70        s32 ret_val = 0;
  71
  72        if (size > mbx->size)
  73                ret_val = IXGBE_ERR_MBX;
  74
  75        else if (mbx->ops.write)
  76                ret_val = mbx->ops.write(hw, msg, size, mbx_id);
  77
  78        return ret_val;
  79}
  80
  81/**
  82 *  ixgbe_check_for_msg - checks to see if someone sent us mail
  83 *  @hw: pointer to the HW structure
  84 *  @mbx_id: id of mailbox to check
  85 *
  86 *  returns SUCCESS if the Status bit was found or else ERR_MBX
  87 **/
  88s32 ixgbe_check_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
  89{
  90        struct ixgbe_mbx_info *mbx = &hw->mbx;
  91        s32 ret_val = IXGBE_ERR_MBX;
  92
  93        if (mbx->ops.check_for_msg)
  94                ret_val = mbx->ops.check_for_msg(hw, mbx_id);
  95
  96        return ret_val;
  97}
  98
  99/**
 100 *  ixgbe_check_for_ack - checks to see if someone sent us ACK
 101 *  @hw: pointer to the HW structure
 102 *  @mbx_id: id of mailbox to check
 103 *
 104 *  returns SUCCESS if the Status bit was found or else ERR_MBX
 105 **/
 106s32 ixgbe_check_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
 107{
 108        struct ixgbe_mbx_info *mbx = &hw->mbx;
 109        s32 ret_val = IXGBE_ERR_MBX;
 110
 111        if (mbx->ops.check_for_ack)
 112                ret_val = mbx->ops.check_for_ack(hw, mbx_id);
 113
 114        return ret_val;
 115}
 116
 117/**
 118 *  ixgbe_check_for_rst - checks to see if other side has reset
 119 *  @hw: pointer to the HW structure
 120 *  @mbx_id: id of mailbox to check
 121 *
 122 *  returns SUCCESS if the Status bit was found or else ERR_MBX
 123 **/
 124s32 ixgbe_check_for_rst(struct ixgbe_hw *hw, u16 mbx_id)
 125{
 126        struct ixgbe_mbx_info *mbx = &hw->mbx;
 127        s32 ret_val = IXGBE_ERR_MBX;
 128
 129        if (mbx->ops.check_for_rst)
 130                ret_val = mbx->ops.check_for_rst(hw, mbx_id);
 131
 132        return ret_val;
 133}
 134
 135/**
 136 *  ixgbe_poll_for_msg - Wait for message notification
 137 *  @hw: pointer to the HW structure
 138 *  @mbx_id: id of mailbox to write
 139 *
 140 *  returns SUCCESS if it successfully received a message notification
 141 **/
 142static s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
 143{
 144        struct ixgbe_mbx_info *mbx = &hw->mbx;
 145        int countdown = mbx->timeout;
 146
 147        if (!countdown || !mbx->ops.check_for_msg)
 148                goto out;
 149
 150        while (countdown && mbx->ops.check_for_msg(hw, mbx_id)) {
 151                countdown--;
 152                if (!countdown)
 153                        break;
 154                udelay(mbx->usec_delay);
 155        }
 156
 157out:
 158        return countdown ? 0 : IXGBE_ERR_MBX;
 159}
 160
 161/**
 162 *  ixgbe_poll_for_ack - Wait for message acknowledgement
 163 *  @hw: pointer to the HW structure
 164 *  @mbx_id: id of mailbox to write
 165 *
 166 *  returns SUCCESS if it successfully received a message acknowledgement
 167 **/
 168static s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
 169{
 170        struct ixgbe_mbx_info *mbx = &hw->mbx;
 171        int countdown = mbx->timeout;
 172
 173        if (!countdown || !mbx->ops.check_for_ack)
 174                goto out;
 175
 176        while (countdown && mbx->ops.check_for_ack(hw, mbx_id)) {
 177                countdown--;
 178                if (!countdown)
 179                        break;
 180                udelay(mbx->usec_delay);
 181        }
 182
 183out:
 184        return countdown ? 0 : IXGBE_ERR_MBX;
 185}
 186
 187/**
 188 *  ixgbe_read_posted_mbx - Wait for message notification and receive message
 189 *  @hw: pointer to the HW structure
 190 *  @msg: The message buffer
 191 *  @size: Length of buffer
 192 *  @mbx_id: id of mailbox to write
 193 *
 194 *  returns SUCCESS if it successfully received a message notification and
 195 *  copied it into the receive buffer.
 196 **/
 197static s32 ixgbe_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size,
 198                                 u16 mbx_id)
 199{
 200        struct ixgbe_mbx_info *mbx = &hw->mbx;
 201        s32 ret_val = IXGBE_ERR_MBX;
 202
 203        if (!mbx->ops.read)
 204                goto out;
 205
 206        ret_val = ixgbe_poll_for_msg(hw, mbx_id);
 207
 208        /* if ack received read message, otherwise we timed out */
 209        if (!ret_val)
 210                ret_val = mbx->ops.read(hw, msg, size, mbx_id);
 211out:
 212        return ret_val;
 213}
 214
 215/**
 216 *  ixgbe_write_posted_mbx - Write a message to the mailbox, wait for ack
 217 *  @hw: pointer to the HW structure
 218 *  @msg: The message buffer
 219 *  @size: Length of buffer
 220 *  @mbx_id: id of mailbox to write
 221 *
 222 *  returns SUCCESS if it successfully copied message into the buffer and
 223 *  received an ack to that message within delay * timeout period
 224 **/
 225static s32 ixgbe_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size,
 226                           u16 mbx_id)
 227{
 228        struct ixgbe_mbx_info *mbx = &hw->mbx;
 229        s32 ret_val = IXGBE_ERR_MBX;
 230
 231        /* exit if either we can't write or there isn't a defined timeout */
 232        if (!mbx->ops.write || !mbx->timeout)
 233                goto out;
 234
 235        /* send msg */
 236        ret_val = mbx->ops.write(hw, msg, size, mbx_id);
 237
 238        /* if msg sent wait until we receive an ack */
 239        if (!ret_val)
 240                ret_val = ixgbe_poll_for_ack(hw, mbx_id);
 241out:
 242        return ret_val;
 243}
 244
 245static s32 ixgbe_check_for_bit_pf(struct ixgbe_hw *hw, u32 mask, s32 index)
 246{
 247        u32 mbvficr = IXGBE_READ_REG(hw, IXGBE_MBVFICR(index));
 248        s32 ret_val = IXGBE_ERR_MBX;
 249
 250        if (mbvficr & mask) {
 251                ret_val = 0;
 252                IXGBE_WRITE_REG(hw, IXGBE_MBVFICR(index), mask);
 253        }
 254
 255        return ret_val;
 256}
 257
 258/**
 259 *  ixgbe_check_for_msg_pf - checks to see if the VF has sent mail
 260 *  @hw: pointer to the HW structure
 261 *  @vf_number: the VF index
 262 *
 263 *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
 264 **/
 265static s32 ixgbe_check_for_msg_pf(struct ixgbe_hw *hw, u16 vf_number)
 266{
 267        s32 ret_val = IXGBE_ERR_MBX;
 268        s32 index = IXGBE_MBVFICR_INDEX(vf_number);
 269        u32 vf_bit = vf_number % 16;
 270
 271        if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFREQ_VF1 << vf_bit,
 272                                    index)) {
 273                ret_val = 0;
 274                hw->mbx.stats.reqs++;
 275        }
 276
 277        return ret_val;
 278}
 279
 280/**
 281 *  ixgbe_check_for_ack_pf - checks to see if the VF has ACKed
 282 *  @hw: pointer to the HW structure
 283 *  @vf_number: the VF index
 284 *
 285 *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
 286 **/
 287static s32 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_number)
 288{
 289        s32 ret_val = IXGBE_ERR_MBX;
 290        s32 index = IXGBE_MBVFICR_INDEX(vf_number);
 291        u32 vf_bit = vf_number % 16;
 292
 293        if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFACK_VF1 << vf_bit,
 294                                    index)) {
 295                ret_val = 0;
 296                hw->mbx.stats.acks++;
 297        }
 298
 299        return ret_val;
 300}
 301
 302/**
 303 *  ixgbe_check_for_rst_pf - checks to see if the VF has reset
 304 *  @hw: pointer to the HW structure
 305 *  @vf_number: the VF index
 306 *
 307 *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
 308 **/
 309static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_number)
 310{
 311        u32 reg_offset = (vf_number < 32) ? 0 : 1;
 312        u32 vf_shift = vf_number % 32;
 313        u32 vflre = 0;
 314        s32 ret_val = IXGBE_ERR_MBX;
 315
 316        switch (hw->mac.type) {
 317        case ixgbe_mac_82599EB:
 318                vflre = IXGBE_READ_REG(hw, IXGBE_VFLRE(reg_offset));
 319                break;
 320        case ixgbe_mac_X540:
 321                vflre = IXGBE_READ_REG(hw, IXGBE_VFLREC(reg_offset));
 322                break;
 323        default:
 324                break;
 325        }
 326
 327        if (vflre & (1 << vf_shift)) {
 328                ret_val = 0;
 329                IXGBE_WRITE_REG(hw, IXGBE_VFLREC(reg_offset), (1 << vf_shift));
 330                hw->mbx.stats.rsts++;
 331        }
 332
 333        return ret_val;
 334}
 335
 336/**
 337 *  ixgbe_obtain_mbx_lock_pf - obtain mailbox lock
 338 *  @hw: pointer to the HW structure
 339 *  @vf_number: the VF index
 340 *
 341 *  return SUCCESS if we obtained the mailbox lock
 342 **/
 343static s32 ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_number)
 344{
 345        s32 ret_val = IXGBE_ERR_MBX;
 346        u32 p2v_mailbox;
 347
 348        /* Take ownership of the buffer */
 349        IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_PFU);
 350
 351        /* reserve mailbox for vf use */
 352        p2v_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_number));
 353        if (p2v_mailbox & IXGBE_PFMAILBOX_PFU)
 354                ret_val = 0;
 355
 356        return ret_val;
 357}
 358
 359/**
 360 *  ixgbe_write_mbx_pf - Places a message in the mailbox
 361 *  @hw: pointer to the HW structure
 362 *  @msg: The message buffer
 363 *  @size: Length of buffer
 364 *  @vf_number: the VF index
 365 *
 366 *  returns SUCCESS if it successfully copied message into the buffer
 367 **/
 368static s32 ixgbe_write_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
 369                              u16 vf_number)
 370{
 371        s32 ret_val;
 372        u16 i;
 373
 374        /* lock the mailbox to prevent pf/vf race condition */
 375        ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number);
 376        if (ret_val)
 377                goto out_no_write;
 378
 379        /* flush msg and acks as we are overwriting the message buffer */
 380        ixgbe_check_for_msg_pf(hw, vf_number);
 381        ixgbe_check_for_ack_pf(hw, vf_number);
 382
 383        /* copy the caller specified message to the mailbox memory buffer */
 384        for (i = 0; i < size; i++)
 385                IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i, msg[i]);
 386
 387        /* Interrupt VF to tell it a message has been sent and release buffer*/
 388        IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_STS);
 389
 390        /* update stats */
 391        hw->mbx.stats.msgs_tx++;
 392
 393out_no_write:
 394        return ret_val;
 395
 396}
 397
 398/**
 399 *  ixgbe_read_mbx_pf - Read a message from the mailbox
 400 *  @hw: pointer to the HW structure
 401 *  @msg: The message buffer
 402 *  @size: Length of buffer
 403 *  @vf_number: the VF index
 404 *
 405 *  This function copies a message from the mailbox buffer to the caller's
 406 *  memory buffer.  The presumption is that the caller knows that there was
 407 *  a message due to a VF request so no polling for message is needed.
 408 **/
 409static s32 ixgbe_read_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
 410                             u16 vf_number)
 411{
 412        s32 ret_val;
 413        u16 i;
 414
 415        /* lock the mailbox to prevent pf/vf race condition */
 416        ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number);
 417        if (ret_val)
 418                goto out_no_read;
 419
 420        /* copy the message to the mailbox memory buffer */
 421        for (i = 0; i < size; i++)
 422                msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i);
 423
 424        /* Acknowledge the message and release buffer */
 425        IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_ACK);
 426
 427        /* update stats */
 428        hw->mbx.stats.msgs_rx++;
 429
 430out_no_read:
 431        return ret_val;
 432}
 433
 434#ifdef CONFIG_PCI_IOV
 435/**
 436 *  ixgbe_init_mbx_params_pf - set initial values for pf mailbox
 437 *  @hw: pointer to the HW structure
 438 *
 439 *  Initializes the hw->mbx struct to correct values for pf mailbox
 440 */
 441void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw)
 442{
 443        struct ixgbe_mbx_info *mbx = &hw->mbx;
 444
 445        if (hw->mac.type != ixgbe_mac_82599EB &&
 446            hw->mac.type != ixgbe_mac_X540)
 447                return;
 448
 449        mbx->timeout = 0;
 450        mbx->usec_delay = 0;
 451
 452        mbx->stats.msgs_tx = 0;
 453        mbx->stats.msgs_rx = 0;
 454        mbx->stats.reqs = 0;
 455        mbx->stats.acks = 0;
 456        mbx->stats.rsts = 0;
 457
 458        mbx->size = IXGBE_VFMAILBOX_SIZE;
 459}
 460#endif /* CONFIG_PCI_IOV */
 461
 462struct ixgbe_mbx_operations mbx_ops_generic = {
 463        .read                   = ixgbe_read_mbx_pf,
 464        .write                  = ixgbe_write_mbx_pf,
 465        .read_posted            = ixgbe_read_posted_mbx,
 466        .write_posted           = ixgbe_write_posted_mbx,
 467        .check_for_msg          = ixgbe_check_for_msg_pf,
 468        .check_for_ack          = ixgbe_check_for_ack_pf,
 469        .check_for_rst          = ixgbe_check_for_rst_pf,
 470};
 471
 472