Skip to content

Commit

Permalink
tty: n_gsm: Fix long delays with control frame timeouts in ADM mode
Browse files Browse the repository at this point in the history
commit e9ec22547986dd32c5c70da78107ce35dbff1344 upstream.

Commit ea3d8465ab9b ("tty: n_gsm: Allow ADM response in addition to UA for
control dlci") added support for DLCI to stay in Asynchronous Disconnected
Mode (ADM). But we still get long delays waiting for commands to other
DLCI to complete:

--> 5) C: SABM(P)
Q>  0) C: UIH(F)
Q>  0) C: UIH(F)
Q>  0) C: UIH(F)
...

This happens because gsm_control_send() sets cretries timer to T2 that is
by default set to 34. This will cause resend for T2 times for the control
frame. In ADM mode, we will never get a response so the control frame, so
retries are just delaying all the commands.

Let's fix the issue by setting DLCI_MODE_ADM flag after detecting the ADM
mode for the control DLCI. Then we can use that in gsm_control_send() to
set retries to 1. This means the control frame will be sent once allowing
the other end at an opportunity to switch from ADM to ABM mode.

Note that retries will be decremented in gsm_control_retransmit() so
we don't want to set it to 0 here.

Fixes: ea3d8465ab9b ("tty: n_gsm: Allow ADM response in addition to UA for control dlci")
Cc: [email protected]
Cc: Alan Cox <[email protected]>
Cc: Dan Williams <[email protected]>
Cc: Jiri Prchal <[email protected]>
Cc: Jiri Slaby <[email protected]>
Cc: Marcel Partap <[email protected]>
Cc: Merlijn Wajer <[email protected]>
Cc: Michael Nazzareno Trimarchi <[email protected]>
Cc: Michael Scott <[email protected]>
Cc: Pavel Machek <[email protected]>
Cc: Peter Hurley <[email protected]>
Cc: Russ Gorby <[email protected]>
Cc: Sascha Hauer <[email protected]>
Cc: Sebastian Reichel <[email protected]>
Signed-off-by: Tony Lindgren <[email protected]>
Cc: stable <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
tmlind authored and gregkh committed May 1, 2018
1 parent 6a506d4 commit 11723a9
Showing 1 changed file with 11 additions and 1 deletion.
12 changes: 11 additions & 1 deletion drivers/tty/n_gsm.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,9 @@ struct gsm_dlci {
struct mutex mutex;

/* Link layer */
int mode;
#define DLCI_MODE_ABM 0 /* Normal Asynchronous Balanced Mode */
#define DLCI_MODE_ADM 1 /* Asynchronous Disconnected Mode */
spinlock_t lock; /* Protects the internal state */
struct timer_list t1; /* Retransmit timer for SABM and UA */
int retries;
Expand Down Expand Up @@ -1380,7 +1383,13 @@ static struct gsm_control *gsm_control_send(struct gsm_mux *gsm,
ctrl->data = data;
ctrl->len = clen;
gsm->pending_cmd = ctrl;
gsm->cretries = gsm->n2;

/* If DLCI0 is in ADM mode skip retries, it won't respond */
if (gsm->dlci[0]->mode == DLCI_MODE_ADM)
gsm->cretries = 1;
else
gsm->cretries = gsm->n2;

mod_timer(&gsm->t2_timer, jiffies + gsm->t2 * HZ / 100);
gsm_control_transmit(gsm, ctrl);
spin_unlock_irqrestore(&gsm->control_lock, flags);
Expand Down Expand Up @@ -1488,6 +1497,7 @@ static void gsm_dlci_t1(unsigned long data)
if (debug & 8)
pr_info("DLCI %d opening in ADM mode.\n",
dlci->addr);
dlci->mode = DLCI_MODE_ADM;
gsm_dlci_open(dlci);
} else {
gsm_dlci_close(dlci);
Expand Down

0 comments on commit 11723a9

Please sign in to comment.