iPXE
igbvf_mbx.c
Go to the documentation of this file.
00001 /*******************************************************************************
00002 
00003   Intel(R) 82576 Virtual Function Linux driver
00004   Copyright(c) 1999 - 2008 Intel Corporation.
00005 
00006   This program is free software; you can redistribute it and/or modify it
00007   under the terms and conditions of the GNU General Public License,
00008   version 2, as published by the Free Software Foundation.
00009 
00010   This program is distributed in the hope it will be useful, but WITHOUT
00011   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
00013   more details.
00014 
00015   You should have received a copy of the GNU General Public License along with
00016   this program; if not, write to the Free Software Foundation, Inc.,
00017   51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
00018 
00019   The full GNU General Public License is included in this distribution in
00020   the file called "COPYING".
00021 
00022   Contact Information:
00023   Linux NICS <linux.nics@intel.com>
00024   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
00025   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
00026 
00027 *******************************************************************************/
00028 
00029 FILE_LICENCE ( GPL2_ONLY );
00030 
00031 #include "igbvf_mbx.h"
00032 
00033 /**
00034  *  igbvf_poll_for_msg - Wait for message notification
00035  *  @hw: pointer to the HW structure
00036  *  @mbx_id: id of mailbox to write
00037  *
00038  *  returns SUCCESS if it successfully received a message notification
00039  **/
00040 static s32 igbvf_poll_for_msg(struct e1000_hw *hw, u16 mbx_id)
00041 {
00042         struct e1000_mbx_info *mbx = &hw->mbx;
00043         int countdown = mbx->timeout;
00044 
00045         DEBUGFUNC("igbvf_poll_for_msg");
00046 
00047         if (!countdown || !mbx->ops.check_for_msg)
00048                 goto out;
00049 
00050         while (countdown && mbx->ops.check_for_msg(hw, mbx_id)) {
00051                 countdown--;
00052                 if (!countdown)
00053                         break;
00054                 usec_delay(mbx->usec_delay);
00055         }
00056 
00057         /* if we failed, all future posted messages fail until reset */
00058         if (!countdown)
00059                 mbx->timeout = 0;
00060 out:
00061         return countdown ? E1000_SUCCESS : -E1000_ERR_MBX;
00062 }
00063 
00064 /**
00065  *  igbvf_poll_for_ack - Wait for message acknowledgement
00066  *  @hw: pointer to the HW structure
00067  *  @mbx_id: id of mailbox to write
00068  *
00069  *  returns SUCCESS if it successfully received a message acknowledgement
00070  **/
00071 static s32 igbvf_poll_for_ack(struct e1000_hw *hw, u16 mbx_id)
00072 {
00073         struct e1000_mbx_info *mbx = &hw->mbx;
00074         int countdown = mbx->timeout;
00075 
00076         DEBUGFUNC("igbvf_poll_for_ack");
00077 
00078         if (!countdown || !mbx->ops.check_for_ack)
00079                 goto out;
00080 
00081         while (countdown && mbx->ops.check_for_ack(hw, mbx_id)) {
00082                 countdown--;
00083                 if (!countdown)
00084                         break;
00085                 usec_delay(mbx->usec_delay);
00086         }
00087 
00088         /* if we failed, all future posted messages fail until reset */
00089         if (!countdown)
00090                 mbx->timeout = 0;
00091 out:
00092         return countdown ? E1000_SUCCESS : -E1000_ERR_MBX;
00093 }
00094 
00095 /**
00096  *  igbvf_read_posted_mbx - Wait for message notification and receive message
00097  *  @hw: pointer to the HW structure
00098  *  @msg: The message buffer
00099  *  @size: Length of buffer
00100  *  @mbx_id: id of mailbox to write
00101  *
00102  *  returns SUCCESS if it successfully received a message notification and
00103  *  copied it into the receive buffer.
00104  **/
00105 static s32 igbvf_read_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size,
00106                                  u16 mbx_id)
00107 {
00108         struct e1000_mbx_info *mbx = &hw->mbx;
00109         s32 ret_val = -E1000_ERR_MBX;
00110 
00111         DEBUGFUNC("igbvf_read_posted_mbx");
00112 
00113         if (!mbx->ops.read)
00114                 goto out;
00115 
00116         ret_val = igbvf_poll_for_msg(hw, mbx_id);
00117 
00118         /* if ack received read message, otherwise we timed out */
00119         if (!ret_val)
00120                 ret_val = mbx->ops.read(hw, msg, size, mbx_id);
00121 out:
00122         return ret_val;
00123 }
00124 
00125 /**
00126  *  igbvf_write_posted_mbx - Write a message to the mailbox, wait for ack
00127  *  @hw: pointer to the HW structure
00128  *  @msg: The message buffer
00129  *  @size: Length of buffer
00130  *  @mbx_id: id of mailbox to write
00131  *
00132  *  returns SUCCESS if it successfully copied message into the buffer and
00133  *  received an ack to that message within delay * timeout period
00134  **/
00135 static s32 igbvf_write_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size,
00136                                   u16 mbx_id)
00137 {
00138         struct e1000_mbx_info *mbx = &hw->mbx;
00139         s32 ret_val = -E1000_ERR_MBX;
00140 
00141         DEBUGFUNC("igbvf_write_posted_mbx");
00142 
00143         /* exit if either we can't write or there isn't a defined timeout */
00144         if (!mbx->ops.write || !mbx->timeout)
00145                 goto out;
00146 
00147         /* send msg */
00148         ret_val = mbx->ops.write(hw, msg, size, mbx_id);
00149 
00150         /* if msg sent wait until we receive an ack */
00151         if (!ret_val)
00152                 ret_val = igbvf_poll_for_ack(hw, mbx_id);
00153 out:
00154         return ret_val;
00155 }
00156 
00157 /**
00158  *  igbvf_init_mbx_ops_generic - Initialize NVM function pointers
00159  *  @hw: pointer to the HW structure
00160  *
00161  *  Setups up the function pointers to no-op functions
00162  **/
00163 void igbvf_init_mbx_ops_generic(struct e1000_hw *hw)
00164 {
00165         struct e1000_mbx_info *mbx = &hw->mbx;
00166         mbx->ops.read_posted = igbvf_read_posted_mbx;
00167         mbx->ops.write_posted = igbvf_write_posted_mbx;
00168 }
00169 
00170 /**
00171  *  igbvf_read_v2p_mailbox - read v2p mailbox
00172  *  @hw: pointer to the HW structure
00173  *
00174  *  This function is used to read the v2p mailbox without losing the read to
00175  *  clear status bits.
00176  **/
00177 static u32 igbvf_read_v2p_mailbox(struct e1000_hw *hw)
00178 {
00179         u32 v2p_mailbox = E1000_READ_REG(hw, E1000_V2PMAILBOX(0));
00180 
00181         v2p_mailbox |= hw->dev_spec.vf.v2p_mailbox;
00182         hw->dev_spec.vf.v2p_mailbox |= v2p_mailbox & E1000_V2PMAILBOX_R2C_BITS;
00183 
00184         return v2p_mailbox;
00185 }
00186 
00187 /**
00188  *  igbvf_check_for_bit_vf - Determine if a status bit was set
00189  *  @hw: pointer to the HW structure
00190  *  @mask: bitmask for bits to be tested and cleared
00191  *
00192  *  This function is used to check for the read to clear bits within
00193  *  the V2P mailbox.
00194  **/
00195 static s32 igbvf_check_for_bit_vf(struct e1000_hw *hw, u32 mask)
00196 {
00197         u32 v2p_mailbox = igbvf_read_v2p_mailbox(hw);
00198         s32 ret_val = -E1000_ERR_MBX;
00199 
00200         if (v2p_mailbox & mask)
00201                 ret_val = E1000_SUCCESS;
00202 
00203         hw->dev_spec.vf.v2p_mailbox &= ~mask;
00204 
00205         return ret_val;
00206 }
00207 
00208 /**
00209  *  igbvf_check_for_msg_vf - checks to see if the PF has sent mail
00210  *  @hw: pointer to the HW structure
00211  *  @mbx_id: id of mailbox to check
00212  *
00213  *  returns SUCCESS if the PF has set the Status bit or else ERR_MBX
00214  **/
00215 static s32 igbvf_check_for_msg_vf(struct e1000_hw *hw, u16 mbx_id __unused)
00216 {
00217         s32 ret_val = -E1000_ERR_MBX;
00218 
00219         DEBUGFUNC("igbvf_check_for_msg_vf");
00220 
00221         if (!igbvf_check_for_bit_vf(hw, E1000_V2PMAILBOX_PFSTS)) {
00222                 ret_val = E1000_SUCCESS;
00223                 hw->mbx.stats.reqs++;
00224         }
00225 
00226         return ret_val;
00227 }
00228 
00229 /**
00230  *  igbvf_check_for_ack_vf - checks to see if the PF has ACK'd
00231  *  @hw: pointer to the HW structure
00232  *  @mbx_id: id of mailbox to check
00233  *
00234  *  returns SUCCESS if the PF has set the ACK bit or else ERR_MBX
00235  **/
00236 static s32 igbvf_check_for_ack_vf(struct e1000_hw *hw, u16 mbx_id __unused)
00237 {
00238         s32 ret_val = -E1000_ERR_MBX;
00239 
00240         DEBUGFUNC("igbvf_check_for_ack_vf");
00241 
00242         if (!igbvf_check_for_bit_vf(hw, E1000_V2PMAILBOX_PFACK)) {
00243                 ret_val = E1000_SUCCESS;
00244                 hw->mbx.stats.acks++;
00245         }
00246 
00247         return ret_val;
00248 }
00249 
00250 /**
00251  *  igbvf_check_for_rst_vf - checks to see if the PF has reset
00252  *  @hw: pointer to the HW structure
00253  *  @mbx_id: id of mailbox to check
00254  *
00255  *  returns true if the PF has set the reset done bit or else false
00256  **/
00257 static s32 igbvf_check_for_rst_vf(struct e1000_hw *hw, u16 mbx_id __unused)
00258 {
00259         s32 ret_val = -E1000_ERR_MBX;
00260 
00261         DEBUGFUNC("igbvf_check_for_rst_vf");
00262 
00263         if (!igbvf_check_for_bit_vf(hw, (E1000_V2PMAILBOX_RSTD |
00264                                          E1000_V2PMAILBOX_RSTI))) {
00265                 ret_val = E1000_SUCCESS;
00266                 hw->mbx.stats.rsts++;
00267         }
00268 
00269         return ret_val;
00270 }
00271 
00272 /**
00273  *  igbvf_obtain_mbx_lock_vf - obtain mailbox lock
00274  *  @hw: pointer to the HW structure
00275  *
00276  *  return SUCCESS if we obtained the mailbox lock
00277  **/
00278 static s32 igbvf_obtain_mbx_lock_vf(struct e1000_hw *hw)
00279 {
00280         s32 ret_val = -E1000_ERR_MBX;
00281 
00282         DEBUGFUNC("igbvf_obtain_mbx_lock_vf");
00283 
00284         /* Take ownership of the buffer */
00285         E1000_WRITE_REG(hw, E1000_V2PMAILBOX(0), E1000_V2PMAILBOX_VFU);
00286 
00287         /* reserve mailbox for vf use */
00288         if (igbvf_read_v2p_mailbox(hw) & E1000_V2PMAILBOX_VFU)
00289                 ret_val = E1000_SUCCESS;
00290 
00291         return ret_val;
00292 }
00293 
00294 /**
00295  *  igbvf_write_mbx_vf - Write a message to the mailbox
00296  *  @hw: pointer to the HW structure
00297  *  @msg: The message buffer
00298  *  @size: Length of buffer
00299  *  @mbx_id: id of mailbox to write
00300  *
00301  *  returns SUCCESS if it successfully copied message into the buffer
00302  **/
00303 static s32 igbvf_write_mbx_vf(struct e1000_hw *hw, u32 *msg, u16 size,
00304                               u16 mbx_id __unused)
00305 {
00306         s32 ret_val;
00307         u16 i;
00308 
00309 
00310         DEBUGFUNC("igbvf_write_mbx_vf");
00311 
00312         /* lock the mailbox to prevent pf/vf race condition */
00313         ret_val = igbvf_obtain_mbx_lock_vf(hw);
00314         if (ret_val)
00315                 goto out_no_write;
00316 
00317         /* flush msg and acks as we are overwriting the message buffer */
00318         igbvf_check_for_msg_vf(hw, 0);
00319         igbvf_check_for_ack_vf(hw, 0);
00320 
00321         /* copy the caller specified message to the mailbox memory buffer */
00322         for (i = 0; i < size; i++)
00323                 E1000_WRITE_REG_ARRAY(hw, E1000_VMBMEM(0), i, msg[i]);
00324 
00325         /* update stats */
00326         hw->mbx.stats.msgs_tx++;
00327 
00328         /* Drop VFU and interrupt the PF to tell it a message has been sent */
00329         E1000_WRITE_REG(hw, E1000_V2PMAILBOX(0), E1000_V2PMAILBOX_REQ);
00330 
00331 out_no_write:
00332         return ret_val;
00333 }
00334 
00335 /**
00336  *  igbvf_read_mbx_vf - Reads a message from the inbox intended for vf
00337  *  @hw: pointer to the HW structure
00338  *  @msg: The message buffer
00339  *  @size: Length of buffer
00340  *  @mbx_id: id of mailbox to read
00341  *
00342  *  returns SUCCESS if it successfuly read message from buffer
00343  **/
00344 static s32 igbvf_read_mbx_vf(struct e1000_hw *hw, u32 *msg, u16 size,
00345                              u16 mbx_id __unused)
00346 {
00347         s32 ret_val = E1000_SUCCESS;
00348         u16 i;
00349 
00350         DEBUGFUNC("igbvf_read_mbx_vf");
00351 
00352         /* lock the mailbox to prevent pf/vf race condition */
00353         ret_val = igbvf_obtain_mbx_lock_vf(hw);
00354         if (ret_val)
00355                 goto out_no_read;
00356 
00357         /* copy the message from the mailbox memory buffer */
00358         for (i = 0; i < size; i++)
00359                 msg[i] = E1000_READ_REG_ARRAY(hw, E1000_VMBMEM(0), i);
00360 
00361         /* Acknowledge receipt and release mailbox, then we're done */
00362         E1000_WRITE_REG(hw, E1000_V2PMAILBOX(0), E1000_V2PMAILBOX_ACK);
00363 
00364         /* update stats */
00365         hw->mbx.stats.msgs_rx++;
00366 
00367 out_no_read:
00368         return ret_val;
00369 }
00370 
00371 /**
00372  *  igbvf_init_mbx_params_vf - set initial values for vf mailbox
00373  *  @hw: pointer to the HW structure
00374  *
00375  *  Initializes the hw->mbx struct to correct values for vf mailbox
00376  */
00377 s32 igbvf_init_mbx_params_vf(struct e1000_hw *hw)
00378 {
00379         struct e1000_mbx_info *mbx = &hw->mbx;
00380 
00381         /* start mailbox as timed out and let the reset_hw call set the timeout
00382          * value to begin communications */
00383         mbx->timeout = 0;
00384         mbx->usec_delay = E1000_VF_MBX_INIT_DELAY;
00385 
00386         mbx->size = E1000_VFMAILBOX_SIZE;
00387 
00388         mbx->ops.read = igbvf_read_mbx_vf;
00389         mbx->ops.write = igbvf_write_mbx_vf;
00390         mbx->ops.read_posted = igbvf_read_posted_mbx;
00391         mbx->ops.write_posted = igbvf_write_posted_mbx;
00392         mbx->ops.check_for_msg = igbvf_check_for_msg_vf;
00393         mbx->ops.check_for_ack = igbvf_check_for_ack_vf;
00394         mbx->ops.check_for_rst = igbvf_check_for_rst_vf;
00395 
00396         mbx->stats.msgs_tx = 0;
00397         mbx->stats.msgs_rx = 0;
00398         mbx->stats.reqs = 0;
00399         mbx->stats.acks = 0;
00400         mbx->stats.rsts = 0;
00401 
00402         return E1000_SUCCESS;
00403 }
00404