]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.14.34/tty-n_gsm-allow-adm-response-in-addition-to-ua-for-control-dlci.patch
Linux 4.14.95
[thirdparty/kernel/stable-queue.git] / releases / 4.14.34 / tty-n_gsm-allow-adm-response-in-addition-to-ua-for-control-dlci.patch
1 From foo@baz Mon Apr 9 13:58:16 CEST 2018
2 From: Tony Lindgren <tony@atomide.com>
3 Date: Wed, 3 Jan 2018 10:18:03 -0800
4 Subject: tty: n_gsm: Allow ADM response in addition to UA for control dlci
5
6 From: Tony Lindgren <tony@atomide.com>
7
8
9 [ Upstream commit ea3d8465ab9b3e01be329ac5195970a84bef76c5 ]
10
11 Some devices have the control dlci stay in ADM mode instead of the UA
12 mode. This can seen at least on droid 4 when trying to open the ts
13 27.010 mux port. Enabling n_gsm debug mode shows the control dlci
14 always respond with DM to SABM instead of UA:
15
16 # modprobe n_gsm debug=0xff
17 # ldattach -d GSM0710 /dev/ttyS0 &
18 gsmld_output: 00000000: f9 03 3f 01 1c f9
19 --> 0) C: SABM(P)
20 gsmld_receive: 00000000: f9 03 1f 01 36 f9
21 <-- 0) C: DM(P)
22 ...
23 $ minicom -D /dev/gsmtty1
24 minicom: cannot open /dev/gsmtty1: No error information
25 $ strace minicom -D /dev/gsmtty1
26 ...
27 open("/dev/gsmtty1", O_RDWR|O_NOCTTY|O_NONBLOCK|O_LARGEFILE) = -1 EL2HLT
28
29 Note that this is different issue from other n_gsm -EL2HLT issues such
30 as timeouts when the control dlci does not respond at all.
31
32 The ADM mode seems to be a quite common according to "RF Wireless World"
33 article "GSM Issue-UE sends SABM and gets a DM response instead of
34 UA response":
35
36 This issue is most commonly observed in GSM networks where in UE sends
37 SABM and expects network to send UA response but it ends up receiving
38 DM response from the network. SABM stands for Set asynchronous balanced
39 mode, UA stands for Unnumbered Acknowledge and DA stands for
40 Disconnected Mode.
41
42 An RLP entity can be in one of two modes:
43 - Asynchronous Balanced Mode (ABM)
44 - Asynchronous Disconnected Mode (ADM)
45
46 Currently Linux kernel closes the control dlci after several retries
47 in gsm_dlci_t1() on DM. This causes n_gsm /dev/gsmtty ports to produce
48 error code -EL2HLT when trying to open them as the closing of control
49 dlci has already set gsm->dead.
50
51 Let's fix the issue by allowing control dlci stay in ADM mode after the
52 retries so the /dev/gsmtty ports can be opened and used. It seems that
53 it might take several attempts to get any response from the control
54 dlci, so it's best to allow ADM mode only after the SABM retries are
55 done.
56
57 Note that for droid 4 additional patches are needed to mux the ttyS0
58 pins and to toggle RTS gpio_149 to wake up the mdm6600 modem are also
59 needed to use n_gsm. And the mdm6600 modem needs to be powered on.
60
61 Cc: linux-serial@vger.kernel.org
62 Cc: Alan Cox <alan@llwyncelyn.cymru>
63 Cc: Jiri Prchal <jiri.prchal@aksignal.cz>
64 Cc: Jiri Slaby <jslaby@suse.cz>
65 Cc: Marcel Partap <mpartap@gmx.net>
66 Cc: Michael Scott <michael.scott@linaro.org>
67 Cc: Peter Hurley <peter@hurleysoftware.com>
68 Cc: Russ Gorby <russ.gorby@intel.com>
69 Cc: Sascha Hauer <s.hauer@pengutronix.de>
70 Cc: Sebastian Reichel <sre@kernel.org>
71 Signed-off-by: Tony Lindgren <tony@atomide.com>
72 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
73 Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
74 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
75 ---
76 drivers/tty/n_gsm.c | 17 ++++++++++++++---
77 1 file changed, 14 insertions(+), 3 deletions(-)
78
79 --- a/drivers/tty/n_gsm.c
80 +++ b/drivers/tty/n_gsm.c
81 @@ -1463,6 +1463,10 @@ static void gsm_dlci_open(struct gsm_dlc
82 * in which case an opening port goes back to closed and a closing port
83 * is simply put into closed state (any further frames from the other
84 * end will get a DM response)
85 + *
86 + * Some control dlci can stay in ADM mode with other dlci working just
87 + * fine. In that case we can just keep the control dlci open after the
88 + * DLCI_OPENING retries time out.
89 */
90
91 static void gsm_dlci_t1(unsigned long data)
92 @@ -1476,8 +1480,15 @@ static void gsm_dlci_t1(unsigned long da
93 if (dlci->retries) {
94 gsm_command(dlci->gsm, dlci->addr, SABM|PF);
95 mod_timer(&dlci->t1, jiffies + gsm->t1 * HZ / 100);
96 - } else
97 + } else if (!dlci->addr && gsm->control == (DM | PF)) {
98 + if (debug & 8)
99 + pr_info("DLCI %d opening in ADM mode.\n",
100 + dlci->addr);
101 + gsm_dlci_open(dlci);
102 + } else {
103 gsm_dlci_close(dlci);
104 + }
105 +
106 break;
107 case DLCI_CLOSING:
108 dlci->retries--;
109 @@ -1495,8 +1506,8 @@ static void gsm_dlci_t1(unsigned long da
110 * @dlci: DLCI to open
111 *
112 * Commence opening a DLCI from the Linux side. We issue SABM messages
113 - * to the modem which should then reply with a UA, at which point we
114 - * will move into open state. Opening is done asynchronously with retry
115 + * to the modem which should then reply with a UA or ADM, at which point
116 + * we will move into open state. Opening is done asynchronously with retry
117 * running off timers and the responses.
118 */
119