linux/drivers/net/ethernet/intel/igb/e1000_mbx.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/* Copyright(c) 2007 - 2018 Intel Corporation. */
   3
   4#include "e1000_mbx.h"
   5
   6/**
   7 *  igb_read_mbx - Reads a message from the mailbox
   8 *  @hw: pointer to the HW structure
   9 *  @msg: The message buffer
  10 *  @size: Length of buffer
  11 *  @mbx_id: id of mailbox to read
  12 *  @unlock: skip locking or not
  13 *
  14 *  returns SUCCESS if it successfully read message from buffer
  15 **/
  16s32 igb_read_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id,
  17                 bool unlock)
  18{
  19        struct e1000_mbx_info *mbx = &hw->mbx;
  20        s32 ret_val = -E1000_ERR_MBX;
  21
  22        /* limit read to size of mailbox */
  23        if (size > mbx->size)
  24                size = mbx->size;
  25
  26        if (mbx->ops.read)
  27                ret_val = mbx->ops.read(hw, msg, size, mbx_id, unlock);
  28
  29        return ret_val;
  30}
  31
  32/**
  33 *  igb_write_mbx - Write a message to the mailbox
  34 *  @hw: pointer to the HW structure
  35 *  @msg: The message buffer
  36 *  @size: Length of buffer
  37 *  @mbx_id: id of mailbox to write
  38 *
  39 *  returns SUCCESS if it successfully copied message into the buffer
  40 **/
  41s32 igb_write_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
  42{
  43        struct e1000_mbx_info *mbx = &hw->mbx;
  44        s32 ret_val = 0;
  45
  46        if (size > mbx->size)
  47                ret_val = -E1000_ERR_MBX;
  48
  49        else if (mbx->ops.write)
  50                ret_val = mbx->ops.write(hw, msg, size, mbx_id);
  51
  52        return ret_val;
  53}
  54
  55/**
  56 *  igb_check_for_msg - checks to see if someone sent us mail
  57 *  @hw: pointer to the HW structure
  58 *  @mbx_id: id of mailbox to check
  59 *
  60 *  returns SUCCESS if the Status bit was found or else ERR_MBX
  61 **/
  62s32 igb_check_for_msg(struct e1000_hw *hw, u16 mbx_id)
  63{
  64        struct e1000_mbx_info *mbx = &hw->mbx;
  65        s32 ret_val = -E1000_ERR_MBX;
  66
  67        if (mbx->ops.check_for_msg)
  68                ret_val = mbx->ops.check_for_msg(hw, mbx_id);
  69
  70        return ret_val;
  71}
  72
  73/**
  74 *  igb_check_for_ack - checks to see if someone sent us ACK
  75 *  @hw: pointer to the HW structure
  76 *  @mbx_id: id of mailbox to check
  77 *
  78 *  returns SUCCESS if the Status bit was found or else ERR_MBX
  79 **/
  80s32 igb_check_for_ack(struct e1000_hw *hw, u16 mbx_id)
  81{
  82        struct e1000_mbx_info *mbx = &hw->mbx;
  83        s32 ret_val = -E1000_ERR_MBX;
  84
  85        if (mbx->ops.check_for_ack)
  86                ret_val = mbx->ops.check_for_ack(hw, mbx_id);
  87
  88        return ret_val;
  89}
  90
  91/**
  92 *  igb_check_for_rst - checks to see if other side has reset
  93 *  @hw: pointer to the HW structure
  94 *  @mbx_id: id of mailbox to check
  95 *
  96 *  returns SUCCESS if the Status bit was found or else ERR_MBX
  97 **/
  98s32 igb_check_for_rst(struct e1000_hw *hw, u16 mbx_id)
  99{
 100        struct e1000_mbx_info *mbx = &hw->mbx;
 101        s32 ret_val = -E1000_ERR_MBX;
 102
 103        if (mbx->ops.check_for_rst)
 104                ret_val = mbx->ops.check_for_rst(hw, mbx_id);
 105
 106        return ret_val;
 107}
 108
 109/**
 110 *  igb_unlock_mbx - unlock the mailbox
 111 *  @hw: pointer to the HW structure
 112 *  @mbx_id: id of mailbox to check
 113 *
 114 *  returns SUCCESS if the mailbox was unlocked or else ERR_MBX
 115 **/
 116s32 igb_unlock_mbx(struct e1000_hw *hw, u16 mbx_id)
 117{
 118        struct e1000_mbx_info *mbx = &hw->mbx;
 119        s32 ret_val = -E1000_ERR_MBX;
 120
 121        if (mbx->ops.unlock)
 122                ret_val = mbx->ops.unlock(hw, mbx_id);
 123
 124        return ret_val;
 125}
 126
 127/**
 128 *  igb_poll_for_msg - Wait for message notification
 129 *  @hw: pointer to the HW structure
 130 *  @mbx_id: id of mailbox to write
 131 *
 132 *  returns SUCCESS if it successfully received a message notification
 133 **/
 134static s32 igb_poll_for_msg(struct e1000_hw *hw, u16 mbx_id)
 135{
 136        struct e1000_mbx_info *mbx = &hw->mbx;
 137        int countdown = mbx->timeout;
 138
 139        if (!countdown || !mbx->ops.check_for_msg)
 140                goto out;
 141
 142        while (countdown && mbx->ops.check_for_msg(hw, mbx_id)) {
 143                countdown--;
 144                if (!countdown)
 145                        break;
 146                udelay(mbx->usec_delay);
 147        }
 148
 149        /* if we failed, all future posted messages fail until reset */
 150        if (!countdown)
 151                mbx->timeout = 0;
 152out:
 153        return countdown ? 0 : -E1000_ERR_MBX;
 154}
 155
 156/**
 157 *  igb_poll_for_ack - Wait for message acknowledgement
 158 *  @hw: pointer to the HW structure
 159 *  @mbx_id: id of mailbox to write
 160 *
 161 *  returns SUCCESS if it successfully received a message acknowledgement
 162 **/
 163static s32 igb_poll_for_ack(struct e1000_hw *hw, u16 mbx_id)
 164{
 165        struct e1000_mbx_info *mbx = &hw->mbx;
 166        int countdown = mbx->timeout;
 167
 168        if (!countdown || !mbx->ops.check_for_ack)
 169                goto out;
 170
 171        while (countdown && mbx->ops.check_for_ack(hw, mbx_id)) {
 172                countdown--;
 173                if (!countdown)
 174                        break;
 175                udelay(mbx->usec_delay);
 176        }
 177
 178        /* if we failed, all future posted messages fail until reset */
 179        if (!countdown)
 180                mbx->timeout = 0;
 181out:
 182        return countdown ? 0 : -E1000_ERR_MBX;
 183}
 184
 185/**
 186 *  igb_read_posted_mbx - Wait for message notification and receive message
 187 *  @hw: pointer to the HW structure
 188 *  @msg: The message buffer
 189 *  @size: Length of buffer
 190 *  @mbx_id: id of mailbox to write
 191 *
 192 *  returns SUCCESS if it successfully received a message notification and
 193 *  copied it into the receive buffer.
 194 **/
 195static s32 igb_read_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size,
 196                               u16 mbx_id)
 197{
 198        struct e1000_mbx_info *mbx = &hw->mbx;
 199        s32 ret_val = -E1000_ERR_MBX;
 200
 201        if (!mbx->ops.read)
 202                goto out;
 203
 204        ret_val = igb_poll_for_msg(hw, mbx_id);
 205
 206        if (!ret_val)
 207                ret_val = mbx->ops.read(hw, msg, size, mbx_id, true);
 208out:
 209        return ret_val;
 210}
 211
 212/**
 213 *  igb_write_posted_mbx - Write a message to the mailbox, wait for ack
 214 *  @hw: pointer to the HW structure
 215 *  @msg: The message buffer
 216 *  @size: Length of buffer
 217 *  @mbx_id: id of mailbox to write
 218 *
 219 *  returns SUCCESS if it successfully copied message into the buffer and
 220 *  received an ack to that message within delay * timeout period
 221 **/
 222static s32 igb_write_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size,
 223                                u16 mbx_id)
 224{
 225        struct e1000_mbx_info *mbx = &hw->mbx;
 226        s32 ret_val = -E1000_ERR_MBX;
 227
 228        /* exit if either we can't write or there isn't a defined timeout */
 229        if (!mbx->ops.write || !mbx->timeout)
 230                goto out;
 231
 232        /* send msg */
 233        ret_val = mbx->ops.write(hw, msg, size, mbx_id);
 234
 235        /* if msg sent wait until we receive an ack */
 236        if (!ret_val)
 237                ret_val = igb_poll_for_ack(hw, mbx_id);
 238out:
 239        return ret_val;
 240}
 241
 242static s32 igb_check_for_bit_pf(struct e1000_hw *hw, u32 mask)
 243{
 244        u32 mbvficr = rd32(E1000_MBVFICR);
 245        s32 ret_val = -E1000_ERR_MBX;
 246
 247        if (mbvficr & mask) {
 248                ret_val = 0;
 249                wr32(E1000_MBVFICR, mask);
 250        }
 251
 252        return ret_val;
 253}
 254
 255/**
 256 *  igb_check_for_msg_pf - checks to see if the VF has sent mail
 257 *  @hw: pointer to the HW structure
 258 *  @vf_number: the VF index
 259 *
 260 *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
 261 **/
 262static s32 igb_check_for_msg_pf(struct e1000_hw *hw, u16 vf_number)
 263{
 264        s32 ret_val = -E1000_ERR_MBX;
 265
 266        if (!igb_check_for_bit_pf(hw, E1000_MBVFICR_VFREQ_VF1 << vf_number)) {
 267                ret_val = 0;
 268                hw->mbx.stats.reqs++;
 269        }
 270
 271        return ret_val;
 272}
 273
 274/**
 275 *  igb_check_for_ack_pf - checks to see if the VF has ACKed
 276 *  @hw: pointer to the HW structure
 277 *  @vf_number: the VF index
 278 *
 279 *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
 280 **/
 281static s32 igb_check_for_ack_pf(struct e1000_hw *hw, u16 vf_number)
 282{
 283        s32 ret_val = -E1000_ERR_MBX;
 284
 285        if (!igb_check_for_bit_pf(hw, E1000_MBVFICR_VFACK_VF1 << vf_number)) {
 286                ret_val = 0;
 287                hw->mbx.stats.acks++;
 288        }
 289
 290        return ret_val;
 291}
 292
 293/**
 294 *  igb_check_for_rst_pf - checks to see if the VF has reset
 295 *  @hw: pointer to the HW structure
 296 *  @vf_number: the VF index
 297 *
 298 *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
 299 **/
 300static s32 igb_check_for_rst_pf(struct e1000_hw *hw, u16 vf_number)
 301{
 302        u32 vflre = rd32(E1000_VFLRE);
 303        s32 ret_val = -E1000_ERR_MBX;
 304
 305        if (vflre & BIT(vf_number)) {
 306                ret_val = 0;
 307                wr32(E1000_VFLRE, BIT(vf_number));
 308                hw->mbx.stats.rsts++;
 309        }
 310
 311        return ret_val;
 312}
 313
 314/**
 315 *  igb_obtain_mbx_lock_pf - obtain mailbox lock
 316 *  @hw: pointer to the HW structure
 317 *  @vf_number: the VF index
 318 *
 319 *  return SUCCESS if we obtained the mailbox lock
 320 **/
 321static s32 igb_obtain_mbx_lock_pf(struct e1000_hw *hw, u16 vf_number)
 322{
 323        s32 ret_val = -E1000_ERR_MBX;
 324        u32 p2v_mailbox;
 325        int count = 10;
 326
 327        do {
 328                /* Take ownership of the buffer */
 329                wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_PFU);
 330
 331                /* reserve mailbox for vf use */
 332                p2v_mailbox = rd32(E1000_P2VMAILBOX(vf_number));
 333                if (p2v_mailbox & E1000_P2VMAILBOX_PFU) {
 334                        ret_val = 0;
 335                        break;
 336                }
 337                udelay(1000);
 338        } while (count-- > 0);
 339
 340        return ret_val;
 341}
 342
 343/**
 344 *  igb_release_mbx_lock_pf - release mailbox lock
 345 *  @hw: pointer to the HW structure
 346 *  @vf_number: the VF index
 347 *
 348 *  return SUCCESS if we released the mailbox lock
 349 **/
 350static s32 igb_release_mbx_lock_pf(struct e1000_hw *hw, u16 vf_number)
 351{
 352        u32 p2v_mailbox;
 353
 354        /* drop PF lock of mailbox, if set */
 355        p2v_mailbox = rd32(E1000_P2VMAILBOX(vf_number));
 356        if (p2v_mailbox & E1000_P2VMAILBOX_PFU)
 357                wr32(E1000_P2VMAILBOX(vf_number),
 358                     p2v_mailbox & ~E1000_P2VMAILBOX_PFU);
 359
 360        return 0;
 361}
 362
 363/**
 364 *  igb_write_mbx_pf - Places a message in the mailbox
 365 *  @hw: pointer to the HW structure
 366 *  @msg: The message buffer
 367 *  @size: Length of buffer
 368 *  @vf_number: the VF index
 369 *
 370 *  returns SUCCESS if it successfully copied message into the buffer
 371 **/
 372static s32 igb_write_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size,
 373                            u16 vf_number)
 374{
 375        s32 ret_val;
 376        u16 i;
 377
 378        /* lock the mailbox to prevent pf/vf race condition */
 379        ret_val = igb_obtain_mbx_lock_pf(hw, vf_number);
 380        if (ret_val)
 381                goto out_no_write;
 382
 383        /* flush msg and acks as we are overwriting the message buffer */
 384        igb_check_for_msg_pf(hw, vf_number);
 385        igb_check_for_ack_pf(hw, vf_number);
 386
 387        /* copy the caller specified message to the mailbox memory buffer */
 388        for (i = 0; i < size; i++)
 389                array_wr32(E1000_VMBMEM(vf_number), i, msg[i]);
 390
 391        /* Interrupt VF to tell it a message has been sent and release buffer*/
 392        wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_STS);
 393
 394        /* update stats */
 395        hw->mbx.stats.msgs_tx++;
 396
 397out_no_write:
 398        return ret_val;
 399
 400}
 401
 402/**
 403 *  igb_read_mbx_pf - Read a message from the mailbox
 404 *  @hw: pointer to the HW structure
 405 *  @msg: The message buffer
 406 *  @size: Length of buffer
 407 *  @vf_number: the VF index
 408 *  @unlock: unlock the mailbox when done?
 409 *
 410 *  This function copies a message from the mailbox buffer to the caller's
 411 *  memory buffer.  The presumption is that the caller knows that there was
 412 *  a message due to a VF request so no polling for message is needed.
 413 **/
 414static s32 igb_read_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size,
 415                           u16 vf_number, bool unlock)
 416{
 417        s32 ret_val;
 418        u16 i;
 419
 420        /* lock the mailbox to prevent pf/vf race condition */
 421        ret_val = igb_obtain_mbx_lock_pf(hw, vf_number);
 422        if (ret_val)
 423                goto out_no_read;
 424
 425        /* copy the message to the mailbox memory buffer */
 426        for (i = 0; i < size; i++)
 427                msg[i] = array_rd32(E1000_VMBMEM(vf_number), i);
 428
 429        /* Acknowledge the message and release mailbox lock (or not) */
 430        if (unlock)
 431                wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_ACK);
 432        else
 433                wr32(E1000_P2VMAILBOX(vf_number),
 434                     E1000_P2VMAILBOX_ACK | E1000_P2VMAILBOX_PFU);
 435
 436        /* update stats */
 437        hw->mbx.stats.msgs_rx++;
 438
 439out_no_read:
 440        return ret_val;
 441}
 442
 443/**
 444 *  igb_init_mbx_params_pf - set initial values for pf mailbox
 445 *  @hw: pointer to the HW structure
 446 *
 447 *  Initializes the hw->mbx struct to correct values for pf mailbox
 448 */
 449s32 igb_init_mbx_params_pf(struct e1000_hw *hw)
 450{
 451        struct e1000_mbx_info *mbx = &hw->mbx;
 452
 453        mbx->timeout = 0;
 454        mbx->usec_delay = 0;
 455
 456        mbx->size = E1000_VFMAILBOX_SIZE;
 457
 458        mbx->ops.read = igb_read_mbx_pf;
 459        mbx->ops.write = igb_write_mbx_pf;
 460        mbx->ops.read_posted = igb_read_posted_mbx;
 461        mbx->ops.write_posted = igb_write_posted_mbx;
 462        mbx->ops.check_for_msg = igb_check_for_msg_pf;
 463        mbx->ops.check_for_ack = igb_check_for_ack_pf;
 464        mbx->ops.check_for_rst = igb_check_for_rst_pf;
 465        mbx->ops.unlock = igb_release_mbx_lock_pf;
 466
 467        mbx->stats.msgs_tx = 0;
 468        mbx->stats.msgs_rx = 0;
 469        mbx->stats.reqs = 0;
 470        mbx->stats.acks = 0;
 471        mbx->stats.rsts = 0;
 472
 473        return 0;
 474}
 475
 476