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

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

DEFINITIONS

This source file includes following definitions.
  1. e1000_poll_for_msg
  2. e1000_poll_for_ack
  3. e1000_read_posted_mbx
  4. e1000_write_posted_mbx
  5. e1000_read_v2p_mailbox
  6. e1000_check_for_bit_vf
  7. e1000_check_for_msg_vf
  8. e1000_check_for_ack_vf
  9. e1000_check_for_rst_vf
  10. e1000_obtain_mbx_lock_vf
  11. e1000_write_mbx_vf
  12. e1000_read_mbx_vf
  13. e1000_init_mbx_params_vf

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

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