dpdk/drivers/net/ngbe/base/ngbe_mbx.c
<<
>>
Prefs
   1/* SPDX-License-Identifier: BSD-3-Clause
   2 * Copyright(c) 2018-2021 Beijing WangXun Technology Co., Ltd.
   3 * Copyright(c) 2010-2017 Intel Corporation
   4 */
   5
   6#include "ngbe_type.h"
   7
   8#include "ngbe_mbx.h"
   9
  10/**
  11 *  ngbe_read_mbx - Reads a message from the mailbox
  12 *  @hw: pointer to the HW structure
  13 *  @msg: The message buffer
  14 *  @size: Length of buffer
  15 *  @mbx_id: id of mailbox to read
  16 *
  17 *  returns 0 if it successfully read message from buffer
  18 **/
  19s32 ngbe_read_mbx(struct ngbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
  20{
  21        struct ngbe_mbx_info *mbx = &hw->mbx;
  22        s32 ret_val = NGBE_ERR_MBX;
  23
  24        /* limit read to size of mailbox */
  25        if (size > mbx->size)
  26                size = mbx->size;
  27
  28        if (mbx->read)
  29                ret_val = mbx->read(hw, msg, size, mbx_id);
  30
  31        return ret_val;
  32}
  33
  34/**
  35 *  ngbe_write_mbx - Write a message to 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 write
  40 *
  41 *  returns 0 if it successfully copied message into the buffer
  42 **/
  43s32 ngbe_write_mbx(struct ngbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
  44{
  45        struct ngbe_mbx_info *mbx = &hw->mbx;
  46        s32 ret_val = 0;
  47
  48        if (size > mbx->size) {
  49                ret_val = NGBE_ERR_MBX;
  50                DEBUGOUT("Invalid mailbox message size %d", size);
  51        } else if (mbx->write) {
  52                ret_val = mbx->write(hw, msg, size, mbx_id);
  53        }
  54
  55        return ret_val;
  56}
  57
  58/**
  59 *  ngbe_check_for_msg - checks to see if someone sent us mail
  60 *  @hw: pointer to the HW structure
  61 *  @mbx_id: id of mailbox to check
  62 *
  63 *  returns 0 if the Status bit was found or else ERR_MBX
  64 **/
  65s32 ngbe_check_for_msg(struct ngbe_hw *hw, u16 mbx_id)
  66{
  67        struct ngbe_mbx_info *mbx = &hw->mbx;
  68        s32 ret_val = NGBE_ERR_MBX;
  69
  70        if (mbx->check_for_msg)
  71                ret_val = mbx->check_for_msg(hw, mbx_id);
  72
  73        return ret_val;
  74}
  75
  76/**
  77 *  ngbe_check_for_ack - checks to see if someone sent us ACK
  78 *  @hw: pointer to the HW structure
  79 *  @mbx_id: id of mailbox to check
  80 *
  81 *  returns 0 if the Status bit was found or else ERR_MBX
  82 **/
  83s32 ngbe_check_for_ack(struct ngbe_hw *hw, u16 mbx_id)
  84{
  85        struct ngbe_mbx_info *mbx = &hw->mbx;
  86        s32 ret_val = NGBE_ERR_MBX;
  87
  88        if (mbx->check_for_ack)
  89                ret_val = mbx->check_for_ack(hw, mbx_id);
  90
  91        return ret_val;
  92}
  93
  94/**
  95 *  ngbe_check_for_rst - checks to see if other side has reset
  96 *  @hw: pointer to the HW structure
  97 *  @mbx_id: id of mailbox to check
  98 *
  99 *  returns 0 if the Status bit was found or else ERR_MBX
 100 **/
 101s32 ngbe_check_for_rst(struct ngbe_hw *hw, u16 mbx_id)
 102{
 103        struct ngbe_mbx_info *mbx = &hw->mbx;
 104        s32 ret_val = NGBE_ERR_MBX;
 105
 106        if (mbx->check_for_rst)
 107                ret_val = mbx->check_for_rst(hw, mbx_id);
 108
 109        return ret_val;
 110}
 111
 112STATIC s32 ngbe_check_for_bit_pf(struct ngbe_hw *hw, u32 mask)
 113{
 114        u32 mbvficr = rd32(hw, NGBE_MBVFICR);
 115        s32 ret_val = NGBE_ERR_MBX;
 116
 117        if (mbvficr & mask) {
 118                ret_val = 0;
 119                wr32(hw, NGBE_MBVFICR, mask);
 120        }
 121
 122        return ret_val;
 123}
 124
 125/**
 126 *  ngbe_check_for_msg_pf - checks to see if the VF has sent mail
 127 *  @hw: pointer to the HW structure
 128 *  @vf_number: the VF index
 129 *
 130 *  returns 0 if the VF has set the Status bit or else ERR_MBX
 131 **/
 132s32 ngbe_check_for_msg_pf(struct ngbe_hw *hw, u16 vf_number)
 133{
 134        s32 ret_val = NGBE_ERR_MBX;
 135        u32 vf_bit = vf_number;
 136
 137        if (!ngbe_check_for_bit_pf(hw, NGBE_MBVFICR_VFREQ_VF1 << vf_bit)) {
 138                ret_val = 0;
 139                hw->mbx.stats.reqs++;
 140        }
 141
 142        return ret_val;
 143}
 144
 145/**
 146 *  ngbe_check_for_ack_pf - checks to see if the VF has ACKed
 147 *  @hw: pointer to the HW structure
 148 *  @vf_number: the VF index
 149 *
 150 *  returns 0 if the VF has set the Status bit or else ERR_MBX
 151 **/
 152s32 ngbe_check_for_ack_pf(struct ngbe_hw *hw, u16 vf_number)
 153{
 154        s32 ret_val = NGBE_ERR_MBX;
 155        u32 vf_bit = vf_number;
 156
 157        if (!ngbe_check_for_bit_pf(hw, NGBE_MBVFICR_VFACK_VF1 << vf_bit)) {
 158                ret_val = 0;
 159                hw->mbx.stats.acks++;
 160        }
 161
 162        return ret_val;
 163}
 164
 165/**
 166 *  ngbe_check_for_rst_pf - checks to see if the VF has reset
 167 *  @hw: pointer to the HW structure
 168 *  @vf_number: the VF index
 169 *
 170 *  returns 0 if the VF has set the Status bit or else ERR_MBX
 171 **/
 172s32 ngbe_check_for_rst_pf(struct ngbe_hw *hw, u16 vf_number)
 173{
 174        u32 vflre = 0;
 175        s32 ret_val = NGBE_ERR_MBX;
 176
 177        vflre = rd32(hw, NGBE_FLRVFE);
 178        if (vflre & (1 << vf_number)) {
 179                ret_val = 0;
 180                wr32(hw, NGBE_FLRVFEC, (1 << vf_number));
 181                hw->mbx.stats.rsts++;
 182        }
 183
 184        return ret_val;
 185}
 186
 187/**
 188 *  ngbe_obtain_mbx_lock_pf - obtain mailbox lock
 189 *  @hw: pointer to the HW structure
 190 *  @vf_number: the VF index
 191 *
 192 *  return 0 if we obtained the mailbox lock
 193 **/
 194STATIC s32 ngbe_obtain_mbx_lock_pf(struct ngbe_hw *hw, u16 vf_number)
 195{
 196        s32 ret_val = NGBE_ERR_MBX;
 197        u32 p2v_mailbox;
 198
 199        /* Take ownership of the buffer */
 200        wr32(hw, NGBE_MBCTL(vf_number), NGBE_MBCTL_PFU);
 201
 202        /* reserve mailbox for vf use */
 203        p2v_mailbox = rd32(hw, NGBE_MBCTL(vf_number));
 204        if (p2v_mailbox & NGBE_MBCTL_PFU)
 205                ret_val = 0;
 206        else
 207                DEBUGOUT("Failed to obtain mailbox lock for VF%d", vf_number);
 208
 209
 210        return ret_val;
 211}
 212
 213/**
 214 *  ngbe_write_mbx_pf - Places a message in the mailbox
 215 *  @hw: pointer to the HW structure
 216 *  @msg: The message buffer
 217 *  @size: Length of buffer
 218 *  @vf_number: the VF index
 219 *
 220 *  returns 0 if it successfully copied message into the buffer
 221 **/
 222s32 ngbe_write_mbx_pf(struct ngbe_hw *hw, u32 *msg, u16 size, u16 vf_number)
 223{
 224        s32 ret_val;
 225        u16 i;
 226
 227        /* lock the mailbox to prevent pf/vf race condition */
 228        ret_val = ngbe_obtain_mbx_lock_pf(hw, vf_number);
 229        if (ret_val)
 230                goto out_no_write;
 231
 232        /* flush msg and acks as we are overwriting the message buffer */
 233        ngbe_check_for_msg_pf(hw, vf_number);
 234        ngbe_check_for_ack_pf(hw, vf_number);
 235
 236        /* copy the caller specified message to the mailbox memory buffer */
 237        for (i = 0; i < size; i++)
 238                wr32a(hw, NGBE_MBMEM(vf_number), i, msg[i]);
 239
 240        /* Interrupt VF to tell it a message has been sent and release buffer*/
 241        wr32(hw, NGBE_MBCTL(vf_number), NGBE_MBCTL_STS);
 242
 243        /* update stats */
 244        hw->mbx.stats.msgs_tx++;
 245
 246out_no_write:
 247        return ret_val;
 248}
 249
 250/**
 251 *  ngbe_read_mbx_pf - Read a message from the mailbox
 252 *  @hw: pointer to the HW structure
 253 *  @msg: The message buffer
 254 *  @size: Length of buffer
 255 *  @vf_number: the VF index
 256 *
 257 *  This function copies a message from the mailbox buffer to the caller's
 258 *  memory buffer.  The presumption is that the caller knows that there was
 259 *  a message due to a VF request so no polling for message is needed.
 260 **/
 261s32 ngbe_read_mbx_pf(struct ngbe_hw *hw, u32 *msg, u16 size, u16 vf_number)
 262{
 263        s32 ret_val;
 264        u16 i;
 265
 266        /* lock the mailbox to prevent pf/vf race condition */
 267        ret_val = ngbe_obtain_mbx_lock_pf(hw, vf_number);
 268        if (ret_val)
 269                goto out_no_read;
 270
 271        /* copy the message to the mailbox memory buffer */
 272        for (i = 0; i < size; i++)
 273                msg[i] = rd32a(hw, NGBE_MBMEM(vf_number), i);
 274
 275        /* Acknowledge the message and release buffer */
 276        wr32(hw, NGBE_MBCTL(vf_number), NGBE_MBCTL_ACK);
 277
 278        /* update stats */
 279        hw->mbx.stats.msgs_rx++;
 280
 281out_no_read:
 282        return ret_val;
 283}
 284
 285/**
 286 *  ngbe_init_mbx_params_pf - set initial values for pf mailbox
 287 *  @hw: pointer to the HW structure
 288 *
 289 *  Initializes the hw->mbx struct to correct values for pf mailbox
 290 */
 291void ngbe_init_mbx_params_pf(struct ngbe_hw *hw)
 292{
 293        struct ngbe_mbx_info *mbx = &hw->mbx;
 294
 295        mbx->timeout = 0;
 296        mbx->usec_delay = 0;
 297
 298        mbx->size = NGBE_P2VMBX_SIZE;
 299
 300        mbx->stats.msgs_tx = 0;
 301        mbx->stats.msgs_rx = 0;
 302        mbx->stats.reqs = 0;
 303        mbx->stats.acks = 0;
 304        mbx->stats.rsts = 0;
 305}
 306