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 }; 337