struct e1000_mbx_operations {
        s32 (*init_params)(struct e1000_hw *hw);
-       s32 (*read)(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id);
+       s32 (*read)(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id,
+                   bool unlock);
        s32 (*write)(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id);
        s32 (*read_posted)(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id);
        s32 (*write_posted)(struct e1000_hw *hw, u32 *msg, u16 size,
 
  *
  *  returns SUCCESS if it successfully read message from buffer
  **/
-s32 igb_read_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
+s32 igb_read_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id,
+                bool unlock)
 {
        struct e1000_mbx_info *mbx = &hw->mbx;
        s32 ret_val = -E1000_ERR_MBX;
                size = mbx->size;
 
        if (mbx->ops.read)
-               ret_val = mbx->ops.read(hw, msg, size, mbx_id);
+               ret_val = mbx->ops.read(hw, msg, size, mbx_id, unlock);
 
        return ret_val;
 }
        ret_val = igb_poll_for_msg(hw, mbx_id);
 
        if (!ret_val)
-               ret_val = mbx->ops.read(hw, msg, size, mbx_id);
+               ret_val = mbx->ops.read(hw, msg, size, mbx_id, true);
 out:
        return ret_val;
 }
  *  @msg: The message buffer
  *  @size: Length of buffer
  *  @vf_number: the VF index
+ *  @unlock: unlock the mailbox when done?
  *
  *  This function copies a message from the mailbox buffer to the caller's
  *  memory buffer.  The presumption is that the caller knows that there was
  *  a message due to a VF request so no polling for message is needed.
  **/
 static s32 igb_read_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size,
-                          u16 vf_number)
+                          u16 vf_number, bool unlock)
 {
        s32 ret_val;
        u16 i;
        for (i = 0; i < size; i++)
                msg[i] = array_rd32(E1000_VMBMEM(vf_number), i);
 
-       /* Acknowledge the message and release buffer */
-       wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_ACK);
+       /* Acknowledge the message and release mailbox lock (or not) */
+       if (unlock)
+               wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_ACK);
+       else
+               wr32(E1000_P2VMAILBOX(vf_number),
+                    E1000_P2VMAILBOX_ACK | E1000_P2VMAILBOX_PFU);
 
        /* update stats */
        hw->mbx.stats.msgs_rx++;
 
 
 #define E1000_PF_CONTROL_MSG   0x0100 /* PF control message */
 
-s32 igb_read_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id);
+s32 igb_read_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id,
+                bool unlock);
 s32 igb_write_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id);
 s32 igb_check_for_msg(struct e1000_hw *hw, u16 mbx_id);
 s32 igb_check_for_ack(struct e1000_hw *hw, u16 mbx_id);
 
        struct vf_data_storage *vf_data = &adapter->vf_data[vf];
        s32 retval;
 
-       retval = igb_read_mbx(hw, msgbuf, E1000_VFMAILBOX_SIZE, vf);
+       retval = igb_read_mbx(hw, msgbuf, E1000_VFMAILBOX_SIZE, vf, false);
 
        if (retval) {
                /* if receive failed revoke VF CTS stats and restart init */
                dev_err(&pdev->dev, "Error receiving message from VF\n");
                vf_data->flags &= ~IGB_VF_FLAG_CTS;
                if (!time_after(jiffies, vf_data->last_nack + (2 * HZ)))
-                       return;
+                       goto unlock;
                goto out;
        }
 
        /* this is a message we already processed, do nothing */
        if (msgbuf[0] & (E1000_VT_MSGTYPE_ACK | E1000_VT_MSGTYPE_NACK))
-               return;
+               goto unlock;
 
        /* until the vf completes a reset it should not be
         * allowed to start any configuration.
         */
        if (msgbuf[0] == E1000_VF_RESET) {
+               /* unlocks mailbox */
                igb_vf_reset_msg(adapter, vf);
                return;
        }
 
        if (!(vf_data->flags & IGB_VF_FLAG_CTS)) {
                if (!time_after(jiffies, vf_data->last_nack + (2 * HZ)))
-                       return;
+                       goto unlock;
                retval = -1;
                goto out;
        }
        else
                msgbuf[0] |= E1000_VT_MSGTYPE_ACK;
 
+       /* unlocks mailbox */
        igb_write_mbx(hw, msgbuf, 1, vf);
+       return;
+
+unlock:
+       igb_unlock_mbx(hw, vf);
 }
 
 static void igb_msg_task(struct igb_adapter *adapter)