RG500Q-EA — IPv6-only and dual-stack always fail (QMI call_end_reason 241), IPv4 works (Orange Poland)

Setup

  • Module: Quectel RG500Q-EA, firmware RG500QEAAAR13A01M4G

  • Carrier: Orange Poland (MCC 260, MNC 03), LTE / 5G-NSA

  • Host: OpenWrt — driver qmi_wwan_q V1.2.9, QMAP enabled (qmap_mode=1, muxid 0x81), connection manager quectel-cm (QConnectManager Linux V1.6.5)

  • SIM is SIM_READY, PIN disabled

What works

  • IPv4-only on APN internet (IPv4 PDP) connects and works normally.

What fails

  1. IPv6-only — APN internetipv6, IPv6 PDP. quectel-cm always fails at requestSetupDataCall: QMUXResult = 0x1, QMUXError = 0xe call_end_reason = 1, call_end_reason_type = 2, call_end_reason_verbose = 241 (INTERFACE_IN_USE_CONFIG_MATCH) Consistent, regardless of profile/CID/auth/mux.

  2. Dual-stack (separate IPv4 + IPv6 PDN) — the IPv4 context connects and gets an address, but the IPv6 context fails with the same 241; a second quectel-cm then issues requestDeactivateDefaultPDP and tears down the working IPv4 context.

Observation: the network appears to auto-activate the IPv6 context (CID2 internetipv6, +CGACT: 2,1 with a valid IPv6 via AT+CGCONTRDP) on every attach, even when not configured locally — so setup seems to hit a context that is already in use (241). AT+QCFG="ResetFactory" helps only temporarily and is irreversible. The same physical SIM works fine for IPv6 in a ZTE MF286D (raw-ip, no QMAP).

Questions

  1. Why does IPv6-only (APN internetipv6) consistently fail with call_end_reason_verbose 241, while IPv4 on the same SIM and modem works?

  2. Why does dual-stack (separate IPv4 + IPv6 PDN contexts) fail in the same way?

  3. Where are the current official sources for quectel-cm (QConnectManager Linux) and the kernel modules (qmi_wwan_q / QMAP)? We want to confirm we are not running outdated versions.

We can provide full logs (quectel-cm verbose output, AT traces, dmesg) on request.

Hi @secam7
Do you confirm the APN and IPtype is correct during your test?
Use AT+CGDCONT or AT+QICSGP to confirm.

@silvia Yes — APN and IP type are confirmed correct by AT:

AT+CGDCONT?
+CGDCONT: 1,“IPV6”,“internetipv6”,…
+CGDCONT: 2,“IPV6”,“internetipv6”,… (← network-provisioned, +CGACT: 2,1 active even when not configured locally)
+CGDCONT: 3,“IPV4V6”,“sos”,…

AT+CGCONTRDP=2 returns a valid global IPv6 address, gateway and DNS — i.e., the bearer is already up on the network side before quectel-cm runs.

quectel-cm -6 -n 1 -s internetipv6 internet internet pap -i wwan0 -b then hits:
requestSetupDataCall QMUXResult = 0x1, QMUXError = 0xe
call_end_reason 1 / type 2 / verbose 241 (INTERFACE_IN_USE_CONFIG_MATCH)

This is consistent with the modem refusing to start a new IPv6 PDN because one with the same config is already active (auto-provisioned by the network).

We tried AT+QCFG=“ResetFactory” — IPv6 worked briefly, then 241 returned after re-attach (network re-provisions the context). The same SIM works fine for IPv6 on a ZTE MF286D (raw-ip, no QMAP, uses uqmi).

Questions:

  1. Is there a way for quectel-cm to “attach to” an already-active IPv6 PDN (auto-provisioned by the network) instead of trying to create a new one and getting 241? The IPv4 path handles this gracefully — IPv4 setup attaches to the active default bearer.
  2. Are there newer official sources for quectel-cm and qmi_wwan_q than V1.6.5 / V1.2.9 with IPv6 fixes for this scenario?

Dear @secam7
I have sent new version to you via Message, please try.

Hi @silvia,

Following up with a full root-cause analysis and a working minimal fix. This is not an APN/IP-type misconfiguration — the modem and SIM are fine; it is a specific interaction between the operator’s behaviour and quectel-CM’s connect logic. It affects any operator that auto-activates the IPv6 default/secondary PDN at attach (Orange Poland here, but this is a network class, not a one-off).

Setup

  • Modem: RG500Q-EA, FW RG500QEAAAR13A01M4G (..._01.200.01.200)

  • Driver: qmi_wwan_q, RawIP + QMAP, qmap_mode=1, single mux 0x81 → wwan0_1

  • App: QConnectManager_Linux_V1.6.5 (also verified identical code in V1.6.8)

  • Network: Orange PL. internet = IPv4-only PDN (CID1), internetipv6 = IPv6-only PDN (CID2)

The asymmetry
On the same attach:

  • IPv4 (-s internet, CID1 = the LTE attach/default bearer) → START_NETWORK_INTERFACE succeeds, data flows.

  • IPv6 (-s internetipv6, CID2 = a separate PDN) → START_NETWORK_INTERFACE always returns call_end_reason_verbose = 241 (INTERFACE_IN_USE_CONFIG_MATCH).

Why — the network auto-activates CID2 at every attach. AT confirms it (config is IPv4-only, yet CID2 comes up by itself):

+CGDCONT: 1,"IP","internet",...
+CGDCONT: 2,"IPV6","internetipv6",...
+CGACT: 1,1
+CGACT: 2,1        <-- IPv6 PDN already ACTIVE, activated by the network
+CGCONTRDP: 2,6,internetipv6,42.0.15.68.12.208...  <-- real GUA 2a00:f44:cd0:bb66::/64, gw fe80::1, DNS 2a01:1700:3:ffff::9822

Because CID2 is already up, quectel-CM’s fresh IPv6 START_NETWORK_INTERFACE collides with it. Stock quectel-CM has no “adopt existing bearer” path for IPv6 — it just logs the reason and retries forever:

[15:24:21] requestQueryDataCall IPv6ConnectionStatus: DISCONNECTED
[15:24:21] requestSetupDataCall QMUXResult = 0x1, QMUXError = 0xe
[15:24:21] call_end_reason is 1
[15:24:21] call_end_reason_type is 2
[15:24:21] call_end_reason_verbose is 241
[15:24:21] try to requestSetupDataCall 5 second later
[15:24:26] ... call_end_reason_verbose is 241 ... 10 second later
[15:24:36] ... call_end_reason_verbose is 241 ... 20 second later

Proof the modem is fully capable — the IPv6 bearer is healthy; the only problem is the START-vs-already-active collision. If I deactivate CID2 (AT+CGACT=0,2) and immediately issue START, it succeeds and is stable. Note the network re-activates CID2 within < 2 s, so the deactivate+START must be tight:

[15:57:15] (AT) AT+CGACT=0,2          <-- deactivate the auto-active IPv6 PDN
[15:57:15] requestSetupDataCall ... verbose 241  -> retry
[15:57:15] (AT) AT+CGACT=0,2
[15:57:16] requestSetupDataCall WdsConnectionIPv6Handle: 0x227e2330   <-- SUCCESS
[15:57:16] ip -6 address add 2a00:f44:cd0:bb66:4dad:9c7d:258b:a280/64 dev wwan0_1
# ping6 google = 0% loss, stable, single handle, no reconnect loop

Minimal fix (host side, quectel-CM) — in requestSetupDataCall() (identical in V1.6.5 and V1.6.8), on an IPv6 failure, deactivate the matching PDN over the AT port and retry START in a tight loop:

 static int requestSetupDataCall(PROFILE_T *profile, int curIpFamily) {
     ...
+    int v6_race = 0;
     profile->curIpFamily = curIpFamily;
+_setup_start:
     pRequest = ComposeQMUXMsg(QMIType, QMIWDS_START_NETWORK_INTERFACE_REQ, ...);
     err = QmiThreadSendQMITimeout(pRequest, &pResponse, 120 * 1000, __func__);
     qmi_rsp_check();
     if (QMUXResult || QMUXError) {
         ... /* existing call_end_reason / verbose extraction */
         err = le16_to_cpu(pMUXMsg->QMUXMsgHdrResp.QMUXError);
         free(pResponse);
+        /* network auto-activated this IPv6 PDN -> 241; drop it and retry START
+           to win the short (<2s) window before the network brings it back */
+        if (curIpFamily == IpFamilyV6 && v6_race++ < 90) {
+            char at[32];
+            snprintf(at, sizeof(at), "AT+CGACT=0,%d\r", profile->pdp);
+            send_at_to_modem(at);   /* write to the modem AT port, e.g. /dev/ttyUSB2 */
+            usleep(150 * 1000);
+            goto _setup_start;
+        }
         return err;
     }
     ...
 }

This wins in ~2 attempts (< 1 s) and the IPv6 session is then stable. It is harmless on a clean modem (CGACT=0 on a down context just returns, then START succeeds) and does not touch the IPv4 path.

Requests

  1. Preferred (CM side, your code): add an option to quectel-CM to handle verbose 241 on IPv6 by deactivating the auto-active PDN and retrying START (as above), or by adopting/reusing the existing bearer. We have a working reference implementation and can share the full diff.

  2. Optional (firmware): make START_NETWORK_INTERFACE on a secondary IPv6 PDN whose config matches an already-active (network-initiated) bearer reuse it and return its handle — i.e. behave like the IPv4 attach bearer does today — instead of returning 241. That would remove the need for any host workaround.

Happy to provide full logs, a QMI capture, or the complete patch. Thank you!