net/fm10k/base: request reset on mailbox state change
authorQi Zhang <qi.z.zhang@intel.com>
Wed, 8 Mar 2017 06:19:05 +0000 (01:19 -0500)
committerFerruh Yigit <ferruh.yigit@intel.com>
Tue, 4 Apr 2017 13:52:52 +0000 (15:52 +0200)
Multiple IES API resets can cause a race condition where the mailbox
interrupt request bits can be cleared before being handled. This can
leave certain mailbox messages from the PF to be untreated and the PF
will enter in some inactive state. If this situation occurs, the IES API
will initiate a mailbox version reset which, then, trigger a mailbox
state change. Once this mailbox transition occurs (from OPEN to CONNECT
state), a request for reset will be returned.

Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
drivers/net/fm10k/base/fm10k_mbx.c

index 2e70434..16ab98d 100644 (file)
@@ -2066,9 +2066,10 @@ STATIC void fm10k_sm_mbx_create_reply(struct fm10k_hw *hw,
  *  function can also be used to respond to an error as the connection
  *  resetting would also be a means of dealing with errors.
  **/
-STATIC void fm10k_sm_mbx_process_reset(struct fm10k_hw *hw,
-                                      struct fm10k_mbx_info *mbx)
+STATIC s32 fm10k_sm_mbx_process_reset(struct fm10k_hw *hw,
+                                     struct fm10k_mbx_info *mbx)
 {
+       s32 err = FM10K_SUCCESS;
        const enum fm10k_mbx_state state = mbx->state;
 
        switch (state) {
@@ -2081,6 +2082,7 @@ STATIC void fm10k_sm_mbx_process_reset(struct fm10k_hw *hw,
        case FM10K_STATE_OPEN:
                /* flush any incomplete work */
                fm10k_sm_mbx_connect_reset(mbx);
+               err = FM10K_ERR_RESET_REQUESTED;
                break;
        case FM10K_STATE_CONNECT:
                /* Update remote value to match local value */
@@ -2090,6 +2092,8 @@ STATIC void fm10k_sm_mbx_process_reset(struct fm10k_hw *hw,
        }
 
        fm10k_sm_mbx_create_reply(hw, mbx, mbx->tail);
+
+       return err;
 }
 
 /**
@@ -2172,7 +2176,7 @@ STATIC s32 fm10k_sm_mbx_process(struct fm10k_hw *hw,
 
        switch (FM10K_MSG_HDR_FIELD_GET(mbx->mbx_hdr, SM_VER)) {
        case 0:
-               fm10k_sm_mbx_process_reset(hw, mbx);
+               err = fm10k_sm_mbx_process_reset(hw, mbx);
                break;
        case FM10K_SM_MBX_VERSION:
                err = fm10k_sm_mbx_process_version_1(hw, mbx);