root/drivers/net/ethernet/intel/ixgbevf/mbx.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ixgbevf_poll_for_msg
  2. ixgbevf_poll_for_ack
  3. ixgbevf_read_posted_mbx
  4. ixgbevf_write_posted_mbx
  5. ixgbevf_read_v2p_mailbox
  6. ixgbevf_check_for_bit_vf
  7. ixgbevf_check_for_msg_vf
  8. ixgbevf_check_for_ack_vf
  9. ixgbevf_check_for_rst_vf
  10. ixgbevf_obtain_mbx_lock_vf
  11. ixgbevf_write_mbx_vf
  12. ixgbevf_read_mbx_vf
  13. ixgbevf_init_mbx_params_vf

   1 // SPDX-License-Identifier: GPL-2.0
   2 /* Copyright(c) 1999 - 2018 Intel Corporation. */
   3 
   4 #include "mbx.h"
   5 #include "ixgbevf.h"
   6 
   7 /**
   8  *  ixgbevf_poll_for_msg - Wait for message notification
   9  *  @hw: pointer to the HW structure
  10  *
  11  *  returns 0 if it successfully received a message notification
  12  **/
  13 static s32 ixgbevf_poll_for_msg(struct ixgbe_hw *hw)
  14 {
  15         struct ixgbe_mbx_info *mbx = &hw->mbx;
  16         int countdown = mbx->timeout;
  17 
  18         while (countdown && mbx->ops.check_for_msg(hw)) {
  19                 countdown--;
  20                 udelay(mbx->udelay);
  21         }
  22 
  23         /* if we failed, all future posted messages fail until reset */
  24         if (!countdown)
  25                 mbx->timeout = 0;
  26 
  27         return countdown ? 0 : IXGBE_ERR_MBX;
  28 }
  29 
  30 /**
  31  *  ixgbevf_poll_for_ack - Wait for message acknowledgment
  32  *  @hw: pointer to the HW structure
  33  *
  34  *  returns 0 if it successfully received a message acknowledgment
  35  **/
  36 static s32 ixgbevf_poll_for_ack(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_ack(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_read_posted_mbx - Wait for message notification and receive message
  55  *  @hw: pointer to the HW structure
  56  *  @msg: The message buffer
  57  *  @size: Length of buffer
  58  *
  59  *  returns 0 if it successfully received a message notification and
  60  *  copied it into the receive buffer.
  61  **/
  62 static s32 ixgbevf_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size)
  63 {
  64         struct ixgbe_mbx_info *mbx = &hw->mbx;
  65         s32 ret_val = IXGBE_ERR_MBX;
  66 
  67         if (!mbx->ops.read)
  68                 goto out;
  69 
  70         ret_val = ixgbevf_poll_for_msg(hw);
  71 
  72         /* if ack received read message, otherwise we timed out */
  73         if (!ret_val)
  74                 ret_val = mbx->ops.read(hw, msg, size);
  75 out:
  76         return ret_val;
  77 }
  78 
  79 /**
  80  *  ixgbevf_write_posted_mbx - Write a message to the mailbox, wait for ack
  81  *  @hw: pointer to the HW structure
  82  *  @msg: The message buffer
  83  *  @size: Length of buffer
  84  *
  85  *  returns 0 if it successfully copied message into the buffer and
  86  *  received an ack to that message within delay * timeout period
  87  **/
  88 static s32 ixgbevf_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size)
  89 {
  90         struct ixgbe_mbx_info *mbx = &hw->mbx;
  91         s32 ret_val = IXGBE_ERR_MBX;
  92 
  93         /* exit if either we can't write or there isn't a defined timeout */
  94         if (!mbx->ops.write || !mbx->timeout)
  95                 goto out;
  96 
  97         /* send msg */
  98         ret_val = mbx->ops.write(hw, msg, size);
  99 
 100         /* if msg sent wait until we receive an ack */
 101         if (!ret_val)
 102                 ret_val = ixgbevf_poll_for_ack(hw);
 103 out:
 104         return ret_val;
 105 }
 106 
 107 /**
 108  *  ixgbevf_read_v2p_mailbox - read v2p mailbox
 109  *  @hw: pointer to the HW structure
 110  *
 111  *  This function is used to read the v2p mailbox without losing the read to
 112  *  clear status bits.
 113  **/
 114 static u32 ixgbevf_read_v2p_mailbox(struct ixgbe_hw *hw)
 115 {
 116         u32 v2p_mailbox = IXGBE_READ_REG(hw, IXGBE_VFMAILBOX);
 117 
 118         v2p_mailbox |= hw->mbx.v2p_mailbox;
 119         hw->mbx.v2p_mailbox |= v2p_mailbox & IXGBE_VFMAILBOX_R2C_BITS;
 120 
 121         return v2p_mailbox;
 122 }
 123 
 124 /**
 125  *  ixgbevf_check_for_bit_vf - Determine if a status bit was set
 126  *  @hw: pointer to the HW structure
 127  *  @mask: bitmask for bits to be tested and cleared
 128  *
 129  *  This function is used to check for the read to clear bits within
 130  *  the V2P mailbox.
 131  **/
 132 static s32 ixgbevf_check_for_bit_vf(struct ixgbe_hw *hw, u32 mask)
 133 {
 134         u32 v2p_mailbox = ixgbevf_read_v2p_mailbox(hw);
 135         s32 ret_val = IXGBE_ERR_MBX;
 136 
 137         if (v2p_mailbox & mask)
 138                 ret_val = 0;
 139 
 140         hw->mbx.v2p_mailbox &= ~mask;
 141 
 142         return ret_val;
 143 }
 144 
 145 /**
 146  *  ixgbevf_check_for_msg_vf - checks to see if the PF has sent mail
 147  *  @hw: pointer to the HW structure
 148  *
 149  *  returns 0 if the PF has set the Status bit or else ERR_MBX
 150  **/
 151 static s32 ixgbevf_check_for_msg_vf(struct ixgbe_hw *hw)
 152 {
 153         s32 ret_val = IXGBE_ERR_MBX;
 154 
 155         if (!ixgbevf_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFSTS)) {
 156                 ret_val = 0;
 157                 hw->mbx.stats.reqs++;
 158         }
 159 
 160         return ret_val;
 161 }
 162 
 163 /**
 164  *  ixgbevf_check_for_ack_vf - checks to see if the PF has ACK'd
 165  *  @hw: pointer to the HW structure
 166  *
 167  *  returns 0 if the PF has set the ACK bit or else ERR_MBX
 168  **/
 169 static s32 ixgbevf_check_for_ack_vf(struct ixgbe_hw *hw)
 170 {
 171         s32 ret_val = IXGBE_ERR_MBX;
 172 
 173         if (!ixgbevf_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFACK)) {
 174                 ret_val = 0;
 175                 hw->mbx.stats.acks++;
 176         }
 177 
 178         return ret_val;
 179 }
 180 
 181 /**
 182  *  ixgbevf_check_for_rst_vf - checks to see if the PF has reset
 183  *  @hw: pointer to the HW structure
 184  *
 185  *  returns true if the PF has set the reset done bit or else false
 186  **/
 187 static s32 ixgbevf_check_for_rst_vf(struct ixgbe_hw *hw)
 188 {
 189         s32 ret_val = IXGBE_ERR_MBX;
 190 
 191         if (!ixgbevf_check_for_bit_vf(hw, (IXGBE_VFMAILBOX_RSTD |
 192                                            IXGBE_VFMAILBOX_RSTI))) {
 193                 ret_val = 0;
 194                 hw->mbx.stats.rsts++;
 195         }
 196 
 197         return ret_val;
 198 }
 199 
 200 /**
 201  *  ixgbevf_obtain_mbx_lock_vf - obtain mailbox lock
 202  *  @hw: pointer to the HW structure
 203  *
 204  *  return 0 if we obtained the mailbox lock
 205  **/
 206 static s32 ixgbevf_obtain_mbx_lock_vf(struct ixgbe_hw *hw)
 207 {
 208         s32 ret_val = IXGBE_ERR_MBX;
 209 
 210         /* Take ownership of the buffer */
 211         IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_VFU);
 212 
 213         /* reserve mailbox for VF use */
 214         if (ixgbevf_read_v2p_mailbox(hw) & IXGBE_VFMAILBOX_VFU)
 215                 ret_val = 0;
 216 
 217         return ret_val;
 218 }
 219 
 220 /**
 221  *  ixgbevf_write_mbx_vf - Write a message to the mailbox
 222  *  @hw: pointer to the HW structure
 223  *  @msg: The message buffer
 224  *  @size: Length of buffer
 225  *
 226  *  returns 0 if it successfully copied message into the buffer
 227  **/
 228 static s32 ixgbevf_write_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size)
 229 {
 230         s32 ret_val;
 231         u16 i;
 232 
 233         /* lock the mailbox to prevent PF/VF race condition */
 234         ret_val = ixgbevf_obtain_mbx_lock_vf(hw);
 235         if (ret_val)
 236                 goto out_no_write;
 237 
 238         /* flush msg and acks as we are overwriting the message buffer */
 239         ixgbevf_check_for_msg_vf(hw);
 240         ixgbevf_check_for_ack_vf(hw);
 241 
 242         /* copy the caller specified message to the mailbox memory buffer */
 243         for (i = 0; i < size; i++)
 244                 IXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFMBMEM, i, msg[i]);
 245 
 246         /* update stats */
 247         hw->mbx.stats.msgs_tx++;
 248 
 249         /* Drop VFU and interrupt the PF to tell it a message has been sent */
 250         IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_REQ);
 251 
 252 out_no_write:
 253         return ret_val;
 254 }
 255 
 256 /**
 257  *  ixgbevf_read_mbx_vf - Reads a message from the inbox intended for VF
 258  *  @hw: pointer to the HW structure
 259  *  @msg: The message buffer
 260  *  @size: Length of buffer
 261  *
 262  *  returns 0 if it successfully read message from buffer
 263  **/
 264 static s32 ixgbevf_read_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size)
 265 {
 266         s32 ret_val = 0;
 267         u16 i;
 268 
 269         /* lock the mailbox to prevent PF/VF race condition */
 270         ret_val = ixgbevf_obtain_mbx_lock_vf(hw);
 271         if (ret_val)
 272                 goto out_no_read;
 273 
 274         /* copy the message from the mailbox memory buffer */
 275         for (i = 0; i < size; i++)
 276                 msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i);
 277 
 278         /* Acknowledge receipt and release mailbox, then we're done */
 279         IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_ACK);
 280 
 281         /* update stats */
 282         hw->mbx.stats.msgs_rx++;
 283 
 284 out_no_read:
 285         return ret_val;
 286 }
 287 
 288 /**
 289  *  ixgbevf_init_mbx_params_vf - set initial values for VF mailbox
 290  *  @hw: pointer to the HW structure
 291  *
 292  *  Initializes the hw->mbx struct to correct values for VF mailbox
 293  */
 294 static s32 ixgbevf_init_mbx_params_vf(struct ixgbe_hw *hw)
 295 {
 296         struct ixgbe_mbx_info *mbx = &hw->mbx;
 297 
 298         /* start mailbox as timed out and let the reset_hw call set the timeout
 299          * value to begin communications
 300          */
 301         mbx->timeout = 0;
 302         mbx->udelay = IXGBE_VF_MBX_INIT_DELAY;
 303 
 304         mbx->size = IXGBE_VFMAILBOX_SIZE;
 305 
 306         mbx->stats.msgs_tx = 0;
 307         mbx->stats.msgs_rx = 0;
 308         mbx->stats.reqs = 0;
 309         mbx->stats.acks = 0;
 310         mbx->stats.rsts = 0;
 311 
 312         return 0;
 313 }
 314 
 315 const struct ixgbe_mbx_operations ixgbevf_mbx_ops = {
 316         .init_params    = ixgbevf_init_mbx_params_vf,
 317         .read           = ixgbevf_read_mbx_vf,
 318         .write          = ixgbevf_write_mbx_vf,
 319         .read_posted    = ixgbevf_read_posted_mbx,
 320         .write_posted   = ixgbevf_write_posted_mbx,
 321         .check_for_msg  = ixgbevf_check_for_msg_vf,
 322         .check_for_ack  = ixgbevf_check_for_ack_vf,
 323         .check_for_rst  = ixgbevf_check_for_rst_vf,
 324 };
 325 
 326 /* Mailbox operations when running on Hyper-V.
 327  * On Hyper-V, PF/VF communication is not through the
 328  * hardware mailbox; this communication is through
 329  * a software mediated path.
 330  * Most mail box operations are noop while running on
 331  * Hyper-V.
 332  */
 333 const struct ixgbe_mbx_operations ixgbevf_hv_mbx_ops = {
 334         .init_params    = ixgbevf_init_mbx_params_vf,
 335         .check_for_rst  = ixgbevf_check_for_rst_vf,
 336 };

/* [<][>][^][v][top][bottom][index][help] */