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 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 now 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 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
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 | 205 ++++++++++++++++++++++++++++++-
drivers/net/wwan/wwan_core.c | 46 ++++++-
include/linux/wwan.h | 3 +
3 files changed, 252 insertions(+), 2 deletions(-)
--
2.43.0