Thread (3 messages) 3 messages, 1 author, 2d ago

[PATCH net-next v10 0/2] net: wwan: support DTR/RTS on AT ports via MHI IP_CTRL

flat view
WARM2d

From: Peter Hunt <hidden>
Date: 2026-10-13 18:35:20
Also in: linux-arm-msm, lkml

Revision v10 of 10 in this series.

Revisions (10)
  1. v1 [diff vs current]
  2. v2 [diff vs current]
  3. v3 [diff vs current]
  4. v4 [diff vs current]
  5. v5 [diff vs current]
  6. v6 [diff vs current]
  7. v7 [diff vs current]
  8. v8 [diff vs current]
  9. v9 [diff vs current]
  10. v10 current
Qualcomm/Sierra SDX55/SDX65 modems (e.g. EM9291) withhold unsolicited AT
result codes until the host asserts DTR. The in-tree mhi_wwan_ctrl driver
exposes AT ports but never signals DTR, so URCs never reach userspace.

Patch 1 extends the wwan core with an optional ->dtr_rts(port, mdmbits)
port op. The TIOCM bitmask state is tracked in the wwan core, which raises
DTR/RTS on first open of an AT port whose driver implements ->dtr_rts,
drops them on last close (if HUPCL is set, which is the default for AT
ports) and on port removal, and passes the resolved bitmask to the
driver on TIOCMSET/TIOCMBIC/TIOCMBIS.

Patch 2 adds a second mhi_driver to mhi_wwan_ctrl that binds the IP_CTRL
channel and implements ->dtr_rts by sending the host serial state to the
modem over that channel. The existing AT/QMI/MBIM data path is untouched.

This is a two-patch series. The pci_generic patch from v5 that
enumerates the IP_CTRL channel for the Sierra EM919x/EM929x has been
applied to mhi-next by Mani as commit 83c29a55b89e ("bus: mhi: host:
pci_generic: Add IP_CTRL channel for Sierra EM919x/EM929x"). There is no
build dependency between the two, without that commit the IP_CTRL driver
simply never binds and ->dtr_rts is a no-op.

Note on the ->dtr_rts signature (Loic):

In v3 I replaced ->tiocmget/->tiocmset with ->dtr_rts(port, bool on)
modelled on tty_port_operations, and moved the TIOCM handling into the
wwan core, as you suggested on v2. Review of v3 and v4 then pointed out
that a single bool cannot represent the two lines independently. With
TIOCMBIC/TIOCMBIS on one line while the other is in the opposite state,
the line state sent to the modem no longer matches what TIOCMGET reports
(e.g. RTS re-asserted after TIOCMBIC(TIOCM_RTS)).

Since v5 the op keeps the dtr_rts name and the core still owns all TIOCM
handling, but it is passed the resolved TIOCM bitmask instead of a bool,
so the driver can drive DTR and RTS independently. I kept the dtr_rts
name deliberately, following your v2 preference over ->tiocmset, even
though the signature now differs from tty_port_operations.dtr_rts. The
open/close paths still behave as tty_port dtr_rts does. Is this
acceptable to you, or would you prefer a different shape, for example a
bool ->dtr_rts for open/close plus a separate op for the ioctl path?

Changes in v10 (Sashiko review of v9):
- Patch 1: the AT/QCDM ioctl handler only holds ops_lock around the
  termios/TIOCM state, never across a user-memory copy, returns
  -ERESTARTSYS when interrupted, and no longer takes ops_lock for
  ioctls that don't touch that state (TCFLSH, TIOCEXCL and friends,
  and the FIONREAD fallback). Still ops_lock only, as agreed with Loic
- Patch 1: word the TTY comparisons and the ->dtr_rts kernel-doc more
  precisely (the baud rate is not used, removal only drops the lines
  while the port is open, open only once ->start() has succeeded)
- Patch 2: send DTR/RTS changes from a per-port work item that
  coalesces bursts and retries a send that fails because the IP_CTRL UL
  ring is full or memory is short, so the modem always ends up with the
  final state. Stress testing showed rapid toggling could fill the ring
  and drop updates. Loic, I've dropped your Reviewed-by on this patch as
  the send path changed

Changes in v9:
- Patch 1: drop data_lock, so the termios/TIOCM state and ->dtr_rts
  calls are all serialised by ops_lock, which the AT/QCDM ioctl handler
  now takes interruptibly (Loic Poulain)
- Patch 1: raise DTR/RTS inside the existing first-open branch of
  wwan_port_op_start() (Loic Poulain)
- Patch 1: mask TIOCMSET/TIOCMBIS/TIOCMBIC to the output bits, only call
  ->dtr_rts when DTR or RTS changes, and commit TCSETS/TCSETS2 only on a
  successful copy (Sashiko review of v7)
- Patch 2: requeue the IP_CTRL DL sink buffer only from the refill work,
  and disable it with disable_delayed_work_sync() before
  mhi_unprepare_from_transfer() in remove() (Loic Poulain, Sashiko
  review of v7 and v8)
- Patch 2: leave unpreparing to mhi_probe() when probe fails, and name
  the wwan core commit in the commit message (Sashiko review of v7)
- DTR/RTS stays limited to AT ports, as agreed with Loic and Daniele,
  and the ->dtr_rts kernel-doc now says why

Changes in v8 (Loic Poulain's review of v7, no functional change):
- Patch 1: add wwan_port_raise_dtr_rts() as the counterpart of
  wwan_port_drop_dtr_rts() and move the open-path handling into it
- Patch 1: do the AT port and ->dtr_rts checks inside both helpers
- Patch 1: use scoped_guard() for data_lock in the helpers

Changes in v7 (all from the Sashiko review of v6):
- Patch 1: drop DTR/RTS on last close only if HUPCL is set, as a TTY
  does, and default HUPCL on for AT ports so close behaviour is
  unchanged unless userspace clears it with TCSETS
- Patch 1: wwan_remove_port() passes the masked mdmbits rather than 0,
  via a helper shared with the close path
- Patch 2: retry a failed DL sink buffer requeue from a delayed work
  item on -ENOMEM, and log other failures
- Patch 2: note in the commit message that the IP_CTRL channel entry
  for the EM919x/EM929x is 83c29a55b89e in the MHI tree

Changes in v6:
- Rebased onto net-next, dropped the pci_generic patch (now in mhi-next)
- Patch 1: snapshot mdmbits under data_lock before calling ->dtr_rts from
  the open/close paths
- Patch 2: allocate the IP_CTRL DL sink buffer separately instead of
  embedding it in struct mhi_wwan_dtr (DMA safety on non-coherent
  platforms), and do not requeue it when the DL transfer completes with an
  error such as -ENOTCONN during channel teardown

v9: https://lore.kernel.org/netdev/20261012172219.3668624-1-peter.hunt@opengear.com/ (local)
v8: https://lore.kernel.org/netdev/20261007182238.1154851-1-peter.hunt@opengear.com/ (local)
v7: https://lore.kernel.org/netdev/20261006040422.3208888-1-peter.hunt@opengear.com/ (local)
v6: https://lore.kernel.org/netdev/20261001204614.3481089-1-peter.hunt@opengear.com/ (local)
v5: https://lore.kernel.org/netdev/20260819224927.2274790-1-peter.hunt@opengear.com/ (local)
v4: https://lore.kernel.org/netdev/20260816121705.858013-1-peter.hunt@opengear.com/ (local)
v3: https://lore.kernel.org/netdev/20260807215042.2714442-1-peter.hunt@opengear.com/ (local)
v2: https://lore.kernel.org/netdev/20260806155253.3378294-1-peter.hunt@opengear.com/ (local)
v1: https://lore.kernel.org/netdev/20260804233411.1953445-1-peter.hunt@opengear.com/ (local)

Peter Hunt (2):
  net: wwan: core: propagate modem control signals to port drivers
  net: wwan: mhi_wwan_ctrl: drive DTR/RTS via the IP_CTRL channel

 drivers/net/wwan/mhi_wwan_ctrl.c | 262 ++++++++++++++++++++++++++++++-
 drivers/net/wwan/wwan_core.c     | 172 +++++++++++++-------
 include/linux/wwan.h             |   9 ++
 3 files changed, 385 insertions(+), 58 deletions(-)

-- 
2.43.0
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help