|
@@ -304,6 +304,30 @@ static s32 igb_check_for_rst_pf(struct e1000_hw *hw, u16 vf_number)
|
|
|
return ret_val;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * igb_obtain_mbx_lock_pf - obtain mailbox lock
|
|
|
+ * @hw: pointer to the HW structure
|
|
|
+ * @vf_number: the VF index
|
|
|
+ *
|
|
|
+ * return SUCCESS if we obtained the mailbox lock
|
|
|
+ **/
|
|
|
+static s32 igb_obtain_mbx_lock_pf(struct e1000_hw *hw, u16 vf_number)
|
|
|
+{
|
|
|
+ s32 ret_val = -E1000_ERR_MBX;
|
|
|
+ u32 p2v_mailbox;
|
|
|
+
|
|
|
+
|
|
|
+ /* Take ownership of the buffer */
|
|
|
+ wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_PFU);
|
|
|
+
|
|
|
+ /* reserve mailbox for vf use */
|
|
|
+ p2v_mailbox = rd32(E1000_P2VMAILBOX(vf_number));
|
|
|
+ if (p2v_mailbox & E1000_P2VMAILBOX_PFU)
|
|
|
+ ret_val = 0;
|
|
|
+
|
|
|
+ return ret_val;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* igb_write_mbx_pf - Places a message in the mailbox
|
|
|
* @hw: pointer to the HW structure
|
|
@@ -316,27 +340,17 @@ static s32 igb_check_for_rst_pf(struct e1000_hw *hw, u16 vf_number)
|
|
|
static s32 igb_write_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size,
|
|
|
u16 vf_number)
|
|
|
{
|
|
|
- u32 p2v_mailbox;
|
|
|
- s32 ret_val = 0;
|
|
|
+ s32 ret_val;
|
|
|
u16 i;
|
|
|
|
|
|
- /* Take ownership of the buffer */
|
|
|
- wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_PFU);
|
|
|
-
|
|
|
- /* Make sure we have ownership now... */
|
|
|
- p2v_mailbox = rd32(E1000_P2VMAILBOX(vf_number));
|
|
|
- if (!(p2v_mailbox & E1000_P2VMAILBOX_PFU)) {
|
|
|
- /* failed to grab ownership */
|
|
|
- ret_val = -E1000_ERR_MBX;
|
|
|
+ /* lock the mailbox to prevent pf/vf race condition */
|
|
|
+ ret_val = igb_obtain_mbx_lock_pf(hw, vf_number);
|
|
|
+ if (ret_val)
|
|
|
goto out_no_write;
|
|
|
- }
|
|
|
|
|
|
- /*
|
|
|
- * flush any ack or msg which may already be in the queue
|
|
|
- * as they are likely the result of an error
|
|
|
- */
|
|
|
- igb_check_for_ack_pf(hw, vf_number);
|
|
|
+ /* flush msg and acks as we are overwriting the message buffer */
|
|
|
igb_check_for_msg_pf(hw, vf_number);
|
|
|
+ igb_check_for_ack_pf(hw, vf_number);
|
|
|
|
|
|
/* copy the caller specified message to the mailbox memory buffer */
|
|
|
for (i = 0; i < size; i++)
|
|
@@ -367,20 +381,13 @@ out_no_write:
|
|
|
static s32 igb_read_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size,
|
|
|
u16 vf_number)
|
|
|
{
|
|
|
- u32 p2v_mailbox;
|
|
|
- s32 ret_val = 0;
|
|
|
+ s32 ret_val;
|
|
|
u16 i;
|
|
|
|
|
|
- /* Take ownership of the buffer */
|
|
|
- wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_PFU);
|
|
|
-
|
|
|
- /* Make sure we have ownership now... */
|
|
|
- p2v_mailbox = rd32(E1000_P2VMAILBOX(vf_number));
|
|
|
- if (!(p2v_mailbox & E1000_P2VMAILBOX_PFU)) {
|
|
|
- /* failed to grab ownership */
|
|
|
- ret_val = -E1000_ERR_MBX;
|
|
|
+ /* lock the mailbox to prevent pf/vf race condition */
|
|
|
+ ret_val = igb_obtain_mbx_lock_pf(hw, vf_number);
|
|
|
+ if (ret_val)
|
|
|
goto out_no_read;
|
|
|
- }
|
|
|
|
|
|
/* copy the message to the mailbox memory buffer */
|
|
|
for (i = 0; i < size; i++)
|
|
@@ -392,8 +399,6 @@ static s32 igb_read_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size,
|
|
|
/* update stats */
|
|
|
hw->mbx.stats.msgs_rx++;
|
|
|
|
|
|
- ret_val = 0;
|
|
|
-
|
|
|
out_no_read:
|
|
|
return ret_val;
|
|
|
}
|