@@ -111,6 +111,9 @@ MODULE_ALIAS("can-proto-6");
111111#define ISOTP_FC_WT 1 /* wait */
112112#define ISOTP_FC_OVFLW 2 /* overflow */
113113
114+ #define ISOTP_FC_TIMEOUT 1 /* 1 sec */
115+ #define ISOTP_ECHO_TIMEOUT 2 /* 2 secs */
116+
114117enum {
115118 ISOTP_IDLE = 0 ,
116119 ISOTP_WAIT_FIRST_FC ,
@@ -258,7 +261,8 @@ static int isotp_send_fc(struct sock *sk, int ae, u8 flowstatus)
258261 so -> lastrxcf_tstamp = ktime_set (0 , 0 );
259262
260263 /* start rx timeout watchdog */
261- hrtimer_start (& so -> rxtimer , ktime_set (1 , 0 ), HRTIMER_MODE_REL_SOFT );
264+ hrtimer_start (& so -> rxtimer , ktime_set (ISOTP_FC_TIMEOUT , 0 ),
265+ HRTIMER_MODE_REL_SOFT );
262266 return 0 ;
263267}
264268
@@ -344,6 +348,8 @@ static int check_pad(struct isotp_sock *so, struct canfd_frame *cf,
344348 return 0 ;
345349}
346350
351+ static void isotp_send_cframe (struct isotp_sock * so );
352+
347353static int isotp_rcv_fc (struct isotp_sock * so , struct canfd_frame * cf , int ae )
348354{
349355 struct sock * sk = & so -> sk ;
@@ -398,14 +404,15 @@ static int isotp_rcv_fc(struct isotp_sock *so, struct canfd_frame *cf, int ae)
398404 case ISOTP_FC_CTS :
399405 so -> tx .bs = 0 ;
400406 so -> tx .state = ISOTP_SENDING ;
401- /* start cyclic timer for sending CF frame */
402- hrtimer_start (& so -> txtimer , so -> tx_gap ,
407+ /* send CF frame and enable echo timeout handling */
408+ hrtimer_start (& so -> txtimer , ktime_set ( ISOTP_ECHO_TIMEOUT , 0 ) ,
403409 HRTIMER_MODE_REL_SOFT );
410+ isotp_send_cframe (so );
404411 break ;
405412
406413 case ISOTP_FC_WT :
407414 /* start timer to wait for next FC frame */
408- hrtimer_start (& so -> txtimer , ktime_set (1 , 0 ),
415+ hrtimer_start (& so -> txtimer , ktime_set (ISOTP_FC_TIMEOUT , 0 ),
409416 HRTIMER_MODE_REL_SOFT );
410417 break ;
411418
@@ -600,7 +607,7 @@ static int isotp_rcv_cf(struct sock *sk, struct canfd_frame *cf, int ae,
600607 /* perform blocksize handling, if enabled */
601608 if (!so -> rxfc .bs || ++ so -> rx .bs < so -> rxfc .bs ) {
602609 /* start rx timeout watchdog */
603- hrtimer_start (& so -> rxtimer , ktime_set (1 , 0 ),
610+ hrtimer_start (& so -> rxtimer , ktime_set (ISOTP_FC_TIMEOUT , 0 ),
604611 HRTIMER_MODE_REL_SOFT );
605612 return 0 ;
606613 }
@@ -829,7 +836,7 @@ static void isotp_rcv_echo(struct sk_buff *skb, void *data)
829836 struct isotp_sock * so = isotp_sk (sk );
830837 struct canfd_frame * cf = (struct canfd_frame * )skb -> data ;
831838
832- /* only handle my own local echo skb's */
839+ /* only handle my own local echo CF/SF skb's (no FF!) */
833840 if (skb -> sk != sk || so -> cfecho != * (u32 * )cf -> data )
834841 return ;
835842
@@ -849,13 +856,16 @@ static void isotp_rcv_echo(struct sk_buff *skb, void *data)
849856 if (so -> txfc .bs && so -> tx .bs >= so -> txfc .bs ) {
850857 /* stop and wait for FC with timeout */
851858 so -> tx .state = ISOTP_WAIT_FC ;
852- hrtimer_start (& so -> txtimer , ktime_set (1 , 0 ),
859+ hrtimer_start (& so -> txtimer , ktime_set (ISOTP_FC_TIMEOUT , 0 ),
853860 HRTIMER_MODE_REL_SOFT );
854861 return ;
855862 }
856863
857864 /* no gap between data frames needed => use burst mode */
858865 if (!so -> tx_gap ) {
866+ /* enable echo timeout handling */
867+ hrtimer_start (& so -> txtimer , ktime_set (ISOTP_ECHO_TIMEOUT , 0 ),
868+ HRTIMER_MODE_REL_SOFT );
859869 isotp_send_cframe (so );
860870 return ;
861871 }
@@ -879,7 +889,7 @@ static enum hrtimer_restart isotp_tx_timer_handler(struct hrtimer *hrtimer)
879889 /* start timeout for unlikely lost echo skb */
880890 hrtimer_set_expires (& so -> txtimer ,
881891 ktime_add (ktime_get (),
882- ktime_set (2 , 0 )));
892+ ktime_set (ISOTP_ECHO_TIMEOUT , 0 )));
883893 restart = HRTIMER_RESTART ;
884894
885895 /* push out the next consecutive frame */
@@ -907,7 +917,8 @@ static enum hrtimer_restart isotp_tx_timer_handler(struct hrtimer *hrtimer)
907917 break ;
908918
909919 default :
910- WARN_ON_ONCE (1 );
920+ WARN_ONCE (1 , "can-isotp: tx timer state %08X cfecho %08X\n" ,
921+ so -> tx .state , so -> cfecho );
911922 }
912923
913924 return restart ;
@@ -923,7 +934,7 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
923934 struct canfd_frame * cf ;
924935 int ae = (so -> opt .flags & CAN_ISOTP_EXTEND_ADDR ) ? 1 : 0 ;
925936 int wait_tx_done = (so -> opt .flags & CAN_ISOTP_WAIT_TX_DONE ) ? 1 : 0 ;
926- s64 hrtimer_sec = 0 ;
937+ s64 hrtimer_sec = ISOTP_ECHO_TIMEOUT ;
927938 int off ;
928939 int err ;
929940
@@ -942,6 +953,8 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
942953 err = wait_event_interruptible (so -> wait , so -> tx .state == ISOTP_IDLE );
943954 if (err )
944955 goto err_out ;
956+
957+ so -> tx .state = ISOTP_SENDING ;
945958 }
946959
947960 if (!size || size > MAX_MSG_LENGTH ) {
@@ -986,6 +999,10 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
986999 cf = (struct canfd_frame * )skb -> data ;
9871000 skb_put_zero (skb , so -> ll .mtu );
9881001
1002+ /* cfecho should have been zero'ed by init / former isotp_rcv_echo() */
1003+ if (so -> cfecho )
1004+ pr_notice_once ("can-isotp: uninit cfecho %08X\n" , so -> cfecho );
1005+
9891006 /* check for single frame transmission depending on TX_DL */
9901007 if (size <= so -> tx .ll_dl - SF_PCI_SZ4 - ae - off ) {
9911008 /* The message size generally fits into a SingleFrame - good.
@@ -1011,11 +1028,8 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
10111028 else
10121029 cf -> data [ae ] |= size ;
10131030
1014- so -> tx .state = ISOTP_IDLE ;
1015- wake_up_interruptible (& so -> wait );
1016-
1017- /* don't enable wait queue for a single frame transmission */
1018- wait_tx_done = 0 ;
1031+ /* set CF echo tag for isotp_rcv_echo() (SF-mode) */
1032+ so -> cfecho = * (u32 * )cf -> data ;
10191033 } else {
10201034 /* send first frame */
10211035
@@ -1031,31 +1045,23 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
10311045 /* disable wait for FCs due to activated block size */
10321046 so -> txfc .bs = 0 ;
10331047
1034- /* cfecho should have been zero'ed by init */
1035- if (so -> cfecho )
1036- pr_notice_once ("can-isotp: no fc cfecho %08X\n" ,
1037- so -> cfecho );
1038-
1039- /* set consecutive frame echo tag */
1048+ /* set CF echo tag for isotp_rcv_echo() (CF-mode) */
10401049 so -> cfecho = * (u32 * )cf -> data ;
1041-
1042- /* switch directly to ISOTP_SENDING state */
1043- so -> tx .state = ISOTP_SENDING ;
1044-
1045- /* start timeout for unlikely lost echo skb */
1046- hrtimer_sec = 2 ;
10471050 } else {
10481051 /* standard flow control check */
10491052 so -> tx .state = ISOTP_WAIT_FIRST_FC ;
10501053
10511054 /* start timeout for FC */
1052- hrtimer_sec = 1 ;
1053- }
1055+ hrtimer_sec = ISOTP_FC_TIMEOUT ;
10541056
1055- hrtimer_start (& so -> txtimer , ktime_set (hrtimer_sec , 0 ),
1056- HRTIMER_MODE_REL_SOFT );
1057+ /* no CF echo tag for isotp_rcv_echo() (FF-mode) */
1058+ so -> cfecho = 0 ;
1059+ }
10571060 }
10581061
1062+ hrtimer_start (& so -> txtimer , ktime_set (hrtimer_sec , 0 ),
1063+ HRTIMER_MODE_REL_SOFT );
1064+
10591065 /* send the first or only CAN frame */
10601066 cf -> flags = so -> ll .tx_flags ;
10611067
@@ -1068,8 +1074,7 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
10681074 __func__ , ERR_PTR (err ));
10691075
10701076 /* no transmission -> no timeout monitoring */
1071- if (hrtimer_sec )
1072- hrtimer_cancel (& so -> txtimer );
1077+ hrtimer_cancel (& so -> txtimer );
10731078
10741079 /* reset consecutive frame echo tag */
10751080 so -> cfecho = 0 ;
0 commit comments