Skip to content

Feedback request for eSIM #2272

Open
Open

Description

@navidmafi

It might be possible to active the eSIM on your devices. You can refer to this: https://github.com/linux-surface/linux-surface/wiki/eSIM-Setup

Besides model getting stuck in a bad state sometimes and the initial setup requiring a raw MBIM protocol command, please let us know how's your experience with it.

Remember to redact your ICCID in logs, if attached!

Activity

  1. chikara-linux commented on Sep 6, 2026

    @chikara-linux

    Feedback: Surface Go 2 (LTE) — eUICC works, TERMINAL CAPABILITY was not needed

    Thanks for writing the wiki page. I followed it on a Surface Go 2 (LTE), which is not in the
    "Tested devices" list. Short version: the eUICC is present and healthy, lpac chip info succeeded
    on the first attempt, and I did not need the raw TERMINAL CAPABILITY command. The modem never
    got stuck. I have no spare eSIM subscription, so I stopped before profile download.

    I also hit one thing that I think is worth adding to the wiki, and found out why the raw MBIM
    command is needed on this platform — it turns out not to be an lpac limitation.

    Environment

    Device Microsoft Surface Go 2 (LTE), SKU 045e:09a5, cdc_mbim
    Modem firmware 2005-79b1b1-c8-00004.14, carrier config ROW_Generic_3GPP
    Surface UEFI 1.0.31
    OS / kernel Ubuntu 26.04.1, 7.0.0-31-generic
    ModemManager 1.25.95 (plugin: generic)
    libmbim 1.32.0
    lpac 2.3.0.r456.3ff35594ec15, built with -DLPAC_WITH_APDU_MBIM=ON

    Slot layout matches the wiki exactly:

    # mbimcli -d /dev/cdc-wdm0 -p --ms-query-slot-info-status=0
            Slot '0': 'state-active'
    # mbimcli -d /dev/cdc-wdm0 -p --ms-query-slot-info-status=1
            Slot '1': 'state-active-esim-no-profiles'
    

    1. TERMINAL CAPABILITY was not required on this device

    I went straight to lpac chip info without ever sending
    --ms-set-uicc-terminal-capability, and it worked first try — no SelectFailed, no timeout,
    no slot bouncing needed:

    sudo env LPAC_APDU=mbim LPAC_APDU_MBIM_DEVICE=/dev/cdc-wdm0 \
      LPAC_APDU_MBIM_UIM_SLOT=2 LPAC_APDU_MBIM_USE_PROXY=true lpac chip info
    
    {"type":"lpa","payload":{"code":0,"message":"success","data":{
      "eidValue":"<redacted>",
      "EuiccConfiguredAddresses":{"defaultDpAddress":null,"rootDsAddress":"lpa.ds.gsma.com"},
      "EUICCInfo2":{"profileVersion":"2.1.0","svn":"2.2.0","euiccFirmwareVer":"3.1.0",
        "extCardResource":{"installedApplication":0,"freeNonVolatileMemory":937568,"freeVolatileMemory":27548},
        "ts102241Version":"9.2.0","globalplatformVersion":"2.3.0",
        "rspCapability":["additionalProfile","crlSupport","testProfileSupport"],
        "ppVersion":"0.0.2","sasAcreditationNumber":"GO-PA-UP-0421"}}}}

    So the TERMINAL CAPABILITY step looks device- or firmware-dependent rather than universal.
    It might be worth rewording that section as "if ISD-R selection fails with SelectFailed, send
    this first" rather than presenting it as a mandatory step — it would have saved me a state change
    I did not need to make.

    Notable: this eUICC advertises testProfileSupport, with ~915 KB of free NVM and zero installed
    profiles.

    2. lpac's MBIM backend does not restore the slot mapping — even for read-only commands

    This one cost me my LTE connection and I think it deserves an explicit warning on the wiki.

    apdu_interface_connect() in driver/apdu/mbim.c calls select_sim_slot(), which issues
    MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_DEVICE_SLOT_MAPPINGS (set) whenever the current mapping
    differs from LPAC_APDU_MBIM_UIM_SLOT. The teardown path, libapduinterface_fini(), only frees
    userdata — it never puts the mapping back.

    Consequence: running even a purely read-only lpac chip info with LPAC_APDU_MBIM_UIM_SLOT=2
    silently parks the modem's executor on the (empty) eSIM slot and leaves it there after lpac exits.
    My physical SIM went to signal quality: 0% and NetworkManager sat in a retry loop until I ran:

    sudo mbimcli -d /dev/cdc-wdm0 -p --ms-set-device-slot-mappings=0
    sudo systemctl restart ModemManager
    

    The wiki does tell you to bounce the slots at the end of the procedure, but a reader who only runs
    chip info to check whether their device has an eUICC — which is exactly what this feedback request
    invites people to do — will lose cellular connectivity with no indication why. A one-line warning
    plus the restore command near the chip info step would help.

    3. Why the raw MBIM command is needed here: ModemManager's own slot-switch API is broken on this modem

    ModemManager does expose SetPrimarySimSlot() on D-Bus, so in principle none of this needs raw MBIM.
    On this device that API is unusable, in three separate ways.

    Ground truth from MBIM, while the modem is registered on the physical SIM in slot 0:

    # mbimcli -d /dev/cdc-wdm0 -p --ms-query-device-slot-mappings
            Executor '0': slot '0'
    

    But ModemManager reports the opposite:

    readonly ao SimSlots       = ['/org/freedesktop/ModemManager1/SIM/0', '/']
    readonly u  PrimarySimSlot = 2
    

    PrimarySimSlot = 2 means "the eSIM slot is primary", which is wrong — slot 2 is empty, and the
    active connection is running on the physical SIM in slot 1 (MBIM slot 0).

    Both directions of the setter then misbehave:

    # mmcli -m any --set-primary-sim-slot=2
    successfully requested primary SIM switch in modem     <- exit 0, but the executor does NOT move
    # mbimcli -d /dev/cdc-wdm0 -p --ms-query-device-slot-mappings
            Executor '0': slot '0'                          <- unchanged
    
    # mmcli -m any --set-primary-sim-slot=1
    error: couldn't request primary SIM switch: 'GDBus.Error:...Core.Failed:
    QMI protocol error: QMI protocol error (3): 'Internal''
    

    The =2 case reporting success while doing nothing is the nastier of the two: a caller cannot tell
    it failed. (I suspect ModemManager short-circuits because it believes it is already on slot 2 — no
    attempt is logged for that call — but I have not confirmed that in the source.)

    The =1 failure is explained by this log line:

    ModemManager[...]: <msg> [modem0/cdc-wdm0/mbim] MBIM device is QMI capable
    ModemManager[...]: <wrn> [modem0] failed setting primary SIM slot '1': QMI protocol error (3): 'Internal'
    

    ModemManager detects the modem as QMI-capable and routes the slot switch through the QMI-over-MBIM
    path, which this firmware rejects with Internal. The plain MBIM MS Basic Connect Extensions path
    works reliably — I switched slots four times today with --ms-set-device-slot-mappings and it
    succeeded every time.

    So the wiki's use of raw mbimcli is correct, but the reason is not "there is no API" — it is
    "ModemManager's API is broken on this modem". I'll report that upstream separately; mentioning it
    here because it also means a future GUI that implements slot switching via ModemManager would
    silently fail on this device
    , and because it may explain some of the "modem gets stuck in a bad
    state" reports.

    Not tested

    profile download and everything after it. I don't have a disposable eSIM subscription, and most
    carrier activation codes are single-use, so I stopped at the last step that cannot burn one. Happy
    to continue if anyone knows of a test SM-DP+ that serves GSMA test profiles — the eUICC here
    advertises testProfileSupport.

    Identifiers (EID, ICCID, IMEI, IMSI) redacted throughout.
    2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions