net/e1000/base: retry to get HW mailbox lock
authorWenzhuo Lu <wenzhuo.lu@intel.com>
Wed, 23 Nov 2016 17:22:47 +0000 (12:22 -0500)
committerFerruh Yigit <ferruh.yigit@intel.com>
Tue, 17 Jan 2017 18:36:48 +0000 (19:36 +0100)
The driver shouldn't give up if it fails to get the hardware mailbox lock.

This can happen in a situation where the PF-VF communication channel is
heavily loaded and causes complete communications failure between the PF
and VF drivers.

Add a counter and a delay. The driver will now retry ten times,
waiting one millisecond between retries.

Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
drivers/net/e1000/base/e1000_mbx.c

index 6daf16b..a92fd22 100644 (file)
@@ -430,15 +430,21 @@ STATIC s32 e1000_check_for_rst_vf(struct e1000_hw *hw,
 STATIC s32 e1000_obtain_mbx_lock_vf(struct e1000_hw *hw)
 {
        s32 ret_val = -E1000_ERR_MBX;
+       int count = 10;
 
        DEBUGFUNC("e1000_obtain_mbx_lock_vf");
 
-       /* Take ownership of the buffer */
-       E1000_WRITE_REG(hw, E1000_V2PMAILBOX(0), E1000_V2PMAILBOX_VFU);
+       do {
+               /* Take ownership of the buffer */
+               E1000_WRITE_REG(hw, E1000_V2PMAILBOX(0), E1000_V2PMAILBOX_VFU);
 
-       /* reserve mailbox for vf use */
-       if (e1000_read_v2p_mailbox(hw) & E1000_V2PMAILBOX_VFU)
-               ret_val = E1000_SUCCESS;
+               /* reserve mailbox for vf use */
+               if (e1000_read_v2p_mailbox(hw) & E1000_V2PMAILBOX_VFU) {
+                       ret_val = E1000_SUCCESS;
+                       break;
+               }
+               usec_delay(1000);
+       } while (count-- > 0);
 
        return ret_val;
 }
@@ -645,18 +651,26 @@ STATIC s32 e1000_obtain_mbx_lock_pf(struct e1000_hw *hw, u16 vf_number)
 {
        s32 ret_val = -E1000_ERR_MBX;
        u32 p2v_mailbox;
+       int count = 10;
 
        DEBUGFUNC("e1000_obtain_mbx_lock_pf");
 
-       /* Take ownership of the buffer */
-       E1000_WRITE_REG(hw, E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_PFU);
+       do {
+               /* Take ownership of the buffer */
+               E1000_WRITE_REG(hw, E1000_P2VMAILBOX(vf_number),
+                               E1000_P2VMAILBOX_PFU);
 
-       /* reserve mailbox for vf use */
-       p2v_mailbox = E1000_READ_REG(hw, E1000_P2VMAILBOX(vf_number));
-       if (p2v_mailbox & E1000_P2VMAILBOX_PFU)
-               ret_val = E1000_SUCCESS;
+               /* reserve mailbox for pf use */
+               p2v_mailbox = E1000_READ_REG(hw, E1000_P2VMAILBOX(vf_number));
+               if (p2v_mailbox & E1000_P2VMAILBOX_PFU) {
+                       ret_val = E1000_SUCCESS;
+                       break;
+               }
+               usec_delay(1000);
+       } while (count-- > 0);
 
        return ret_val;
+
 }
 
 /**