mirror of
https://github.com/openwrt/openwrt.git
synced 2026-10-22 02:24:54 +04:00
kernel: mhi: disable doorbell burst mode for RM500Q-AE
Add a pending patch that gives the RM500Q-AE its own MHI channel table with doorbell burst mode disabled on its two hardware data channels. With burst mode on, the downlink stalls under sustained multi-stream load when the wwan0 receive work runs on the same CPU as the modem's interrupt, which is where the default packet steering puts it. Uplink keeps working, the MBIM control channel later times out, and only a reboot recovers it. Ringing the channel doorbell by hand restores the link at once, which points at a lost doorbell-mode handshake. Tested on a Xunison Exigo Hub D50 5G: without the patch a single 25-second 16-stream download stalled the downlink; with it, about 200 seconds of multi-stream downloads with CPU0 at up to 100% ran with no stall and no MHI errors. Link: https://patch.msgid.link/20261013-rm500q-db-burst-v1-1-bb850d54e2c4@gmail.com Signed-off-by: Steve Meek <stevemeek82@gmail.com> Link: https://github.com/openwrt/openwrt/pull/25890 Signed-off-by: Robert Marko <robimarko@gmail.com>
This commit is contained in:
1 parent
2961f34115
commit
73b92d95d1
1 file changed
+104
+104
@@ -0,0 +1,104 @@
|
||||
From 12cbac5f694319d48287a44354a5a090b6d85ed0 Mon Sep 17 00:00:00 2001
|
||||
From: Steve Meek <stevemeek82@gmail.com>
|
||||
Date: Tue, 13 Oct 2026 13:04:56 +0100
|
||||
Subject: [PATCH] bus: mhi: host: pci_generic: Disable doorbell burst mode for
|
||||
Quectel RM500Q-AE
|
||||
|
||||
With burst mode enabled on the IP_HW0_MBIM hardware channels, the
|
||||
RM500Q-AE downlink stops under sustained multi-stream load. The MHI
|
||||
state stays M0 and uplink keeps working, but the downlink event ring
|
||||
stops interrupting, and after a while the MBIM control channel times
|
||||
out as well. Only a reboot recovers it.
|
||||
|
||||
At the stall, the last doorbell the host rang on channel 101 covered a
|
||||
single buffer. The host then refilled the ring without ringing again,
|
||||
as db_mode had been cleared, and the device never signalled doorbell
|
||||
mode again, so it never saw the new buffers. Writing the channel 101
|
||||
doorbell by hand with the current ring write pointer restores the
|
||||
downlink immediately.
|
||||
|
||||
It is load dependent: it reproduces within a 25 second 16-stream TCP
|
||||
download when the wwan0 receive work runs on the same CPU as the
|
||||
modem's MSI, and was not seen with that work moved to another CPU.
|
||||
PCIe runtime PM is not involved, as it reproduces with PCIe port PM
|
||||
disabled.
|
||||
|
||||
Give the RM500Q-AE its own channel table with burst mode disabled on
|
||||
the two hardware channels, so the host rings the doorbell on every
|
||||
transfer. Other modems sharing the em1xx table are left unchanged.
|
||||
|
||||
Tested on a Xunison Exigo Hub D50 5G (IPQ5018, RM500Q-AE firmware
|
||||
RM500QAEAAR13A03M4G, 6.18 with this driver): with the receive work on
|
||||
the modem's CPU at up to 100% load, about 200 seconds of multi-stream
|
||||
downloads at up to 135 Mbps, no stall and no MHI errors, where the
|
||||
unpatched driver stalled within the first 25 second run.
|
||||
|
||||
Fixes: f6985f512f82 ("bus: mhi: host: pci_generic: Add Quectel RM500Q-AE support")
|
||||
Assisted-by: LLM
|
||||
Signed-off-by: Steve Meek <stevemeek82@gmail.com>
|
||||
Link: https://patch.msgid.link/20261013-rm500q-db-burst-v1-1-bb850d54e2c4@gmail.com
|
||||
---
|
||||
drivers/bus/mhi/host/pci_generic.c | 49 +++++++++++++++++++++++++++++-
|
||||
1 file changed, 48 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/bus/mhi/host/pci_generic.c
|
||||
+++ b/drivers/bus/mhi/host/pci_generic.c
|
||||
@@ -470,10 +470,57 @@ static const struct mhi_pci_dev_info mhi
|
||||
.sideband_wake = true,
|
||||
};
|
||||
|
||||
+/*
|
||||
+ * The RM500Q-AE stalls its downlink when the host refills the hardware
|
||||
+ * channel in burst mode: the last doorbell covers one buffer, the host
|
||||
+ * then queues the rest without ringing, and the device never signals
|
||||
+ * doorbell mode again. Ring the doorbell on every transfer instead.
|
||||
+ */
|
||||
+#define MHI_CHANNEL_CONFIG_HW_NOBRST(ch_num, ch_name, el_count, ev_ring, d) \
|
||||
+ { \
|
||||
+ .num = ch_num, \
|
||||
+ .name = ch_name, \
|
||||
+ .num_elements = el_count, \
|
||||
+ .event_ring = ev_ring, \
|
||||
+ .dir = d, \
|
||||
+ .ee_mask = BIT(MHI_EE_AMSS), \
|
||||
+ .pollcfg = 0, \
|
||||
+ .doorbell = MHI_DB_BRST_DISABLE, \
|
||||
+ .lpm_notify = false, \
|
||||
+ .offload_channel = false, \
|
||||
+ .doorbell_mode_switch = false, \
|
||||
+ }
|
||||
+
|
||||
+static const struct mhi_channel_config mhi_quectel_rm500q_channels[] = {
|
||||
+ MHI_CHANNEL_CONFIG_UL(0, "NMEA", 32, 0),
|
||||
+ MHI_CHANNEL_CONFIG_DL(1, "NMEA", 32, 0),
|
||||
+ MHI_CHANNEL_CONFIG_UL_SBL(2, "SAHARA", 32, 0),
|
||||
+ MHI_CHANNEL_CONFIG_DL_SBL(3, "SAHARA", 32, 0),
|
||||
+ MHI_CHANNEL_CONFIG_UL(4, "DIAG", 32, 1),
|
||||
+ MHI_CHANNEL_CONFIG_DL(5, "DIAG", 32, 1),
|
||||
+ MHI_CHANNEL_CONFIG_UL(12, "MBIM", 32, 0),
|
||||
+ MHI_CHANNEL_CONFIG_DL(13, "MBIM", 32, 0),
|
||||
+ MHI_CHANNEL_CONFIG_UL(32, "DUN", 32, 0),
|
||||
+ MHI_CHANNEL_CONFIG_DL(33, "DUN", 32, 0),
|
||||
+ MHI_CHANNEL_CONFIG_UL_FP(34, "FIREHOSE", 32, 0),
|
||||
+ MHI_CHANNEL_CONFIG_DL_FP(35, "FIREHOSE", 32, 0),
|
||||
+ MHI_CHANNEL_CONFIG_HW_NOBRST(100, "IP_HW0_MBIM", 128, 2, DMA_TO_DEVICE),
|
||||
+ MHI_CHANNEL_CONFIG_HW_NOBRST(101, "IP_HW0_MBIM", 128, 3, DMA_FROM_DEVICE),
|
||||
+};
|
||||
+
|
||||
+static const struct mhi_controller_config modem_quectel_rm500q_config = {
|
||||
+ .max_channels = 128,
|
||||
+ .timeout_ms = 20000,
|
||||
+ .num_channels = ARRAY_SIZE(mhi_quectel_rm500q_channels),
|
||||
+ .ch_cfg = mhi_quectel_rm500q_channels,
|
||||
+ .num_events = ARRAY_SIZE(mhi_quectel_em1xx_events),
|
||||
+ .event_cfg = mhi_quectel_em1xx_events,
|
||||
+};
|
||||
+
|
||||
static const struct mhi_pci_dev_info mhi_quectel_rm500q_info = {
|
||||
.name = "quectel-rm500q",
|
||||
.edl = "qcom/sdx55m/edl.mbn",
|
||||
- .config = &modem_quectel_em1xx_config,
|
||||
+ .config = &modem_quectel_rm500q_config,
|
||||
.bar_num = MHI_PCI_DEFAULT_BAR_NUM,
|
||||
.dma_data_width = 32,
|
||||
.mru_default = 32768,
|
||||
Reference in new issue
Block a user