1 /******************************************************************************* 2 3 Intel 82599 Virtual Function driver 4 Copyright(c) 1999 - 2012 Intel Corporation. 5 6 This program is free software; you can redistribute it and/or modify it 7 under the terms and conditions of the GNU General Public License, 8 version 2, as published by the Free Software Foundation. 9 10 This program is distributed in the hope it will be useful, but WITHOUT 11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13 more details. 14 15 You should have received a copy of the GNU General Public License along with 16 this program; if not, write to the Free Software Foundation, Inc., 17 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 18 19 The full GNU General Public License is included in this distribution in 20 the file called "COPYING". 21 22 Contact Information: 23 e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> 24 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 25 26 *******************************************************************************/ 27 28 #include "mbx.h" 29 #include "ixgbevf.h" 30 31 /** 32 * ixgbevf_poll_for_msg - Wait for message notification 33 * @hw: pointer to the HW structure 34 * 35 * returns 0 if it successfully received a message notification 36 **/ 37 static s32 ixgbevf_poll_for_msg(struct ixgbe_hw *hw) 38 { 39 struct ixgbe_mbx_info *mbx = &hw->mbx; 40 int countdown = mbx->timeout; 41 42 while (countdown && mbx->ops.check_for_msg(hw)) { 43 countdown--; 44 udelay(mbx->udelay); 45 } 46 47 /* if we failed, all future posted messages fail until reset */ 48 if (!countdown) 49 mbx->timeout = 0; 50 51 return countdown ? 0 : IXGBE_ERR_MBX; 52 } 53 54 /** 55 * ixgbevf_poll_for_ack - Wait for message acknowledgement 56 * @hw: pointer to the HW structure 57 * 58 * returns 0 if it successfully received a message acknowledgement 59 **/ 60 static s32 ixgbevf_poll_for_ack(struct ixgbe_hw *hw) 61 { 62 struct ixgbe_mbx_info *mbx = &hw->mbx; 63 int countdown = mbx->timeout; 64 65 while (countdown && mbx->ops.check_for_ack(hw)) { 66 countdown--; 67 udelay(mbx->udelay); 68 } 69 70 /* if we failed, all future posted messages fail until reset */ 71 if (!countdown) 72 mbx->timeout = 0; 73 74 return countdown ? 0 : IXGBE_ERR_MBX; 75 } 76 77 /** 78 * ixgbevf_read_posted_mbx - Wait for message notification and receive message 79 * @hw: pointer to the HW structure 80 * @msg: The message buffer 81 * @size: Length of buffer 82 * 83 * returns 0 if it successfully received a message notification and 84 * copied it into the receive buffer. 85 **/ 86 static s32 ixgbevf_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size) 87 { 88 struct ixgbe_mbx_info *mbx = &hw->mbx; 89 s32 ret_val = -IXGBE_ERR_MBX; 90 91 if (!mbx->ops.read) 92 goto out; 93 94 ret_val = ixgbevf_poll_for_msg(hw); 95 96 /* if ack received read message, otherwise we timed out */ 97 if (!ret_val) 98 ret_val = mbx->ops.read(hw, msg, size); 99 out: 100 return ret_val; 101 } 102 103 /** 104 * ixgbevf_write_posted_mbx - Write a message to the mailbox, wait for ack 105 * @hw: pointer to the HW structure 106 * @msg: The message buffer 107 * @size: Length of buffer 108 * 109 * returns 0 if it successfully copied message into the buffer and 110 * received an ack to that message within delay * timeout period 111 **/ 112 static s32 ixgbevf_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size) 113 { 114 struct ixgbe_mbx_info *mbx = &hw->mbx; 115 s32 ret_val = -IXGBE_ERR_MBX; 116 117 /* exit if either we can't write or there isn't a defined timeout */ 118 if (!mbx->ops.write || !mbx->timeout) 119 goto out; 120 121 /* send msg */ 122 ret_val = mbx->ops.write(hw, msg, size); 123 124 /* if msg sent wait until we receive an ack */ 125 if (!ret_val) 126 ret_val = ixgbevf_poll_for_ack(hw); 127 out: 128 return ret_val; 129 } 130 131 /** 132 * ixgbevf_read_v2p_mailbox - read v2p mailbox 133 * @hw: pointer to the HW structure 134 * 135 * This function is used to read the v2p mailbox without losing the read to 136 * clear status bits. 137 **/ 138 static u32 ixgbevf_read_v2p_mailbox(struct ixgbe_hw *hw) 139 { 140 u32 v2p_mailbox = IXGBE_READ_REG(hw, IXGBE_VFMAILBOX); 141 142 v2p_mailbox |= hw->mbx.v2p_mailbox; 143 hw->mbx.v2p_mailbox |= v2p_mailbox & IXGBE_VFMAILBOX_R2C_BITS; 144 145 return v2p_mailbox; 146 } 147 148 /** 149 * ixgbevf_check_for_bit_vf - Determine if a status bit was set 150 * @hw: pointer to the HW structure 151 * @mask: bitmask for bits to be tested and cleared 152 * 153 * This function is used to check for the read to clear bits within 154 * the V2P mailbox. 155 **/ 156 static s32 ixgbevf_check_for_bit_vf(struct ixgbe_hw *hw, u32 mask) 157 { 158 u32 v2p_mailbox = ixgbevf_read_v2p_mailbox(hw); 159 s32 ret_val = IXGBE_ERR_MBX; 160 161 if (v2p_mailbox & mask) 162 ret_val = 0; 163 164 hw->mbx.v2p_mailbox &= ~mask; 165 166 return ret_val; 167 } 168 169 /** 170 * ixgbevf_check_for_msg_vf - checks to see if the PF has sent mail 171 * @hw: pointer to the HW structure 172 * 173 * returns 0 if the PF has set the Status bit or else ERR_MBX 174 **/ 175 static s32 ixgbevf_check_for_msg_vf(struct ixgbe_hw *hw) 176 { 177 s32 ret_val = IXGBE_ERR_MBX; 178 179 if (!ixgbevf_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFSTS)) { 180 ret_val = 0; 181 hw->mbx.stats.reqs++; 182 } 183 184 return ret_val; 185 } 186 187 /** 188 * ixgbevf_check_for_ack_vf - checks to see if the PF has ACK'd 189 * @hw: pointer to the HW structure 190 * 191 * returns 0 if the PF has set the ACK bit or else ERR_MBX 192 **/ 193 static s32 ixgbevf_check_for_ack_vf(struct ixgbe_hw *hw) 194 { 195 s32 ret_val = IXGBE_ERR_MBX; 196 197 if (!ixgbevf_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFACK)) { 198 ret_val = 0; 199 hw->mbx.stats.acks++; 200 } 201 202 return ret_val; 203 } 204 205 /** 206 * ixgbevf_check_for_rst_vf - checks to see if the PF has reset 207 * @hw: pointer to the HW structure 208 * 209 * returns true if the PF has set the reset done bit or else false 210 **/ 211 static s32 ixgbevf_check_for_rst_vf(struct ixgbe_hw *hw) 212 { 213 s32 ret_val = IXGBE_ERR_MBX; 214 215 if (!ixgbevf_check_for_bit_vf(hw, (IXGBE_VFMAILBOX_RSTD | 216 IXGBE_VFMAILBOX_RSTI))) { 217 ret_val = 0; 218 hw->mbx.stats.rsts++; 219 } 220 221 return ret_val; 222 } 223 224 /** 225 * ixgbevf_obtain_mbx_lock_vf - obtain mailbox lock 226 * @hw: pointer to the HW structure 227 * 228 * return 0 if we obtained the mailbox lock 229 **/ 230 static s32 ixgbevf_obtain_mbx_lock_vf(struct ixgbe_hw *hw) 231 { 232 s32 ret_val = IXGBE_ERR_MBX; 233 234 /* Take ownership of the buffer */ 235 IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_VFU); 236 237 /* reserve mailbox for vf use */ 238 if (ixgbevf_read_v2p_mailbox(hw) & IXGBE_VFMAILBOX_VFU) 239 ret_val = 0; 240 241 return ret_val; 242 } 243 244 /** 245 * ixgbevf_write_mbx_vf - Write a message to the mailbox 246 * @hw: pointer to the HW structure 247 * @msg: The message buffer 248 * @size: Length of buffer 249 * 250 * returns 0 if it successfully copied message into the buffer 251 **/ 252 static s32 ixgbevf_write_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size) 253 { 254 s32 ret_val; 255 u16 i; 256 257 258 /* lock the mailbox to prevent pf/vf race condition */ 259 ret_val = ixgbevf_obtain_mbx_lock_vf(hw); 260 if (ret_val) 261 goto out_no_write; 262 263 /* flush msg and acks as we are overwriting the message buffer */ 264 ixgbevf_check_for_msg_vf(hw); 265 ixgbevf_check_for_ack_vf(hw); 266 267 /* copy the caller specified message to the mailbox memory buffer */ 268 for (i = 0; i < size; i++) 269 IXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFMBMEM, i, msg[i]); 270 271 /* update stats */ 272 hw->mbx.stats.msgs_tx++; 273 274 /* Drop VFU and interrupt the PF to tell it a message has been sent */ 275 IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_REQ); 276 277 out_no_write: 278 return ret_val; 279 } 280 281 /** 282 * ixgbevf_read_mbx_vf - Reads a message from the inbox intended for vf 283 * @hw: pointer to the HW structure 284 * @msg: The message buffer 285 * @size: Length of buffer 286 * 287 * returns 0 if it successfully read message from buffer 288 **/ 289 static s32 ixgbevf_read_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size) 290 { 291 s32 ret_val = 0; 292 u16 i; 293 294 /* lock the mailbox to prevent pf/vf race condition */ 295 ret_val = ixgbevf_obtain_mbx_lock_vf(hw); 296 if (ret_val) 297 goto out_no_read; 298 299 /* copy the message from the mailbox memory buffer */ 300 for (i = 0; i < size; i++) 301 msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i); 302 303 /* Acknowledge receipt and release mailbox, then we're done */ 304 IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_ACK); 305 306 /* update stats */ 307 hw->mbx.stats.msgs_rx++; 308 309 out_no_read: 310 return ret_val; 311 } 312 313 /** 314 * ixgbevf_init_mbx_params_vf - set initial values for vf mailbox 315 * @hw: pointer to the HW structure 316 * 317 * Initializes the hw->mbx struct to correct values for vf mailbox 318 */ 319 static s32 ixgbevf_init_mbx_params_vf(struct ixgbe_hw *hw) 320 { 321 struct ixgbe_mbx_info *mbx = &hw->mbx; 322 323 /* start mailbox as timed out and let the reset_hw call set the timeout 324 * value to begin communications */ 325 mbx->timeout = 0; 326 mbx->udelay = IXGBE_VF_MBX_INIT_DELAY; 327 328 mbx->size = IXGBE_VFMAILBOX_SIZE; 329 330 mbx->stats.msgs_tx = 0; 331 mbx->stats.msgs_rx = 0; 332 mbx->stats.reqs = 0; 333 mbx->stats.acks = 0; 334 mbx->stats.rsts = 0; 335 336 return 0; 337 } 338 339 const struct ixgbe_mbx_operations ixgbevf_mbx_ops = { 340 .init_params = ixgbevf_init_mbx_params_vf, 341 .read = ixgbevf_read_mbx_vf, 342 .write = ixgbevf_write_mbx_vf, 343 .read_posted = ixgbevf_read_posted_mbx, 344 .write_posted = ixgbevf_write_posted_mbx, 345 .check_for_msg = ixgbevf_check_for_msg_vf, 346 .check_for_ack = ixgbevf_check_for_ack_vf, 347 .check_for_rst = ixgbevf_check_for_rst_vf, 348 }; 349 350