FAILED: patch "[PATCH] tty: n_gsm: fix frame reception handling" failed to apply to 4.14-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 4.14-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 7a0e4b1733b635026a87c023f6d703faf0095e39 Mon Sep 17 00:00:00 2001
From: Daniel Starke <[email protected]>
Date: Thu, 14 Apr 2022 02:42:11 -0700
Subject: [PATCH] tty: n_gsm: fix frame reception handling
The frame checksum (FCS) is currently handled in gsm_queue() after reception of a frame. However, this breaks layering. A workaround with 'received_fcs' was implemented so far.
Furthermore, frames are handled as such even if no end flag was received. Move FCS calculation from gsm_queue() to gsm0_receive() and gsm1_receive(). Also delay gsm_queue() call there until a full frame was received to fix both points.
drivers/tty/n_gsm.c +30 -23
@@ -219,7 +219,6 @@ struct gsm_mux {int encoding;u8 control;u8 fcs; -u8 received_fcs;u8 *txframe;/* TX framing buffer */ /* Method for the receiver side */
@@ -1794,18 +1793,7 @@ static void gsm_queue(struct gsm_mux *gsm)u8 cr;int address;int i, j, k, address_tmp; -/* We have to sneak a look at the packet body to do the FCS. -A somewhat layering violation in the spec */ -if ((gsm->control & ~PF ) ==UI ) - gsm->fcs =gsm_fcs_add_block (gsm->fcs, gsm->buf, gsm->len); -if (gsm->encoding ==0 ) { -/* WARNING: gsm->received_fcs is used for -gsm->encoding = 0 only. -In this case it contain the last piece of data -required to generate final CRC */ - gsm->fcs =gsm_fcs_add (gsm->fcs, gsm->received_fcs); - }if (gsm->fcs !=GOOD_FCS ) { gsm->bad_fcs++;if (debug &4 )
@@ -1993,19 +1981,25 @@ static void gsm0_receive(struct gsm_mux *gsm, unsigned char c)break ;case GSM_DATA :/* Data */ gsm->buf[gsm->count++] = c; -if (gsm->count == gsm->len) +if (gsm->count == gsm->len) { +/* Calculate final FCS for UI frames over all data */ +if ((gsm->control & ~PF ) !=UIH ) { + gsm->fcs =gsm_fcs_add_block (gsm->fcs, gsm->buf, + gsm->count); + } gsm->state =GSM_FCS ; + }break ;case GSM_FCS :/* FCS follows the packet */ - gsm->received_fcs = c; -gsm_queue (gsm); + gsm->fcs =gsm_fcs_add (gsm->fcs, c); gsm->state =GSM_SSOF ;break ;case GSM_SSOF : -if (c ==GSM0_SOF ) { - gsm->state =GSM_SEARCH ; -break ; - } + gsm->state =GSM_SEARCH ; +if (c ==GSM0_SOF ) +gsm_queue (gsm); +else + gsm->bad_size++;break ;default :pr_debug ("%s: unhandled state: %d\n" , __func__, gsm->state);
@@ -2024,11 +2018,24 @@ static void gsm0_receive(struct gsm_mux *gsm, unsigned char c)static void gsm1_receive (struct gsm_mux *gsm,unsigned char c) {if (c ==GSM1_SOF ) { -/* EOF is only valid in frame if we have got to the data state -and received at least one byte (the FCS) */ -if (gsm->state ==GSM_DATA && gsm->count) { -/* Extract the FCS */ +/* EOF is only valid in frame if we have got to the data state */ +if (gsm->state ==GSM_DATA ) { +if (gsm->count <1 ) { +/* Missing FSC */ + gsm->malformed++; + gsm->state =GSM_START ; +return ; + } +/* Remove the FCS from data */ gsm->count--; +if ((gsm->control & ~PF ) !=UIH ) { +/* Calculate final FCS for UI frames over all +* data but FCS +*/ + gsm->fcs =gsm_fcs_add_block (gsm->fcs, gsm->buf, + gsm->count); + } +/* Add the FCS itself to test against GOOD_FCS */ gsm->fcs =gsm_fcs_add (gsm->fcs, gsm->buf[gsm->count]); gsm->len = gsm->count;gsm_queue (gsm);