net/smc: send response to test link signal
authorUrsula Braun <ubraun@linux.ibm.com>
Fri, 10 Aug 2018 15:45:11 +0000 (17:45 +0200)
committerDavid S. Miller <davem@davemloft.net>
Fri, 10 Aug 2018 21:38:43 +0000 (14:38 -0700)
With SMC-D z/OS sends a test link signal every 10 seconds. Linux is
supposed to answer, otherwise the SMC-D connection breaks.

Signed-off-by: Ursula Braun <ubraun@linux.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/smc/smc_ism.c

index cfade7fdcc6d3115d18e9da7b0bfd51b247ed7f7..e36f21ce725208c62164847602e99df91d2c40ba 100644 (file)
@@ -184,6 +184,37 @@ struct smc_ism_event_work {
        struct smcd_event event;
 };
 
+#define ISM_EVENT_REQUEST              0x0001
+#define ISM_EVENT_RESPONSE             0x0002
+#define ISM_EVENT_REQUEST_IR           0x00000001
+#define ISM_EVENT_CODE_TESTLINK                0x83
+
+static void smcd_handle_sw_event(struct smc_ism_event_work *wrk)
+{
+       union {
+               u64     info;
+               struct {
+                       u32             uid;
+                       unsigned short  vlanid;
+                       u16             code;
+               };
+       } ev_info;
+
+       switch (wrk->event.code) {
+       case ISM_EVENT_CODE_TESTLINK:   /* Activity timer */
+               ev_info.info = wrk->event.info;
+               if (ev_info.code == ISM_EVENT_REQUEST) {
+                       ev_info.code = ISM_EVENT_RESPONSE;
+                       wrk->smcd->ops->signal_event(wrk->smcd,
+                                                    wrk->event.tok,
+                                                    ISM_EVENT_REQUEST_IR,
+                                                    ISM_EVENT_CODE_TESTLINK,
+                                                    ev_info.info);
+                       }
+               break;
+       }
+}
+
 /* worker for SMC-D events */
 static void smc_ism_event_work(struct work_struct *work)
 {
@@ -196,6 +227,9 @@ static void smc_ism_event_work(struct work_struct *work)
                break;
        case ISM_EVENT_DMB:
                break;
+       case ISM_EVENT_SWR:     /* Software defined event */
+               smcd_handle_sw_event(wrk);
+               break;
        }
        kfree(wrk);
 }