Skip to content
RPRichard PruittTech & Cyber
Navigation
repo://poppyup/docs/03-datapath-bottlenecks.md

docs/03-datapath-bottlenecks.md

30 KB · 266 lines · markdown · View rendered · Download from the repository page

docs/03-datapath-bottlenecks.md
# PoppyUp — Data-Path & Bottleneck Analysis **Document:** 03-datapath-bottlenecks.md · **Baseline:** v0.3, 2026-09-27 (owner review decisions D1–D13 applied; see ADR §15. v0.2: built-in cellular modem removed, ADR §14) · **Derives from:** `00-architecture-decisions.md` (ADR §2, §3, §5). Requirements that cite these numbers: `01-requirements.md` NFR-010…019. ## 0. The one-line answer In standalone mode PoppyUp is **never the bottleneck**; the network is. The card side delivers 0.3–1.7 GB/s, the best network we can attach (5GBASE-T) takes ~0.5 GB/s, a typical venue drop takes 0.01–0.12 GB/s, and real-world cellular uplink — reached through the user's phone (Wi-Fi hotspot or USB tether on Port B) or a USB cellular adapter, since there is no built-in modem — takes **0.003–0.012 GB/s** — two to three orders of magnitude below the card. In host mode the limiting factor is the USB path chosen by the host: ~3 GB/s over USB4 (Port C, Pro SKU only), ~0.9 GB/s over USB 3.2 Gen2, ~0.4 GB/s via the SoC gadget (Port A, all SKUs), ~0.04 GB/s on a USB 2.0 iPhone. Both host paths present the media read-only by default (D8). 5GBASE-T is the final Ethernet choice (D6, ADR §5). All rates below are decimal (MB/s = 10⁶ B/s). "Raw" is the line rate; "payload" subtracts encoding and protocol overhead; "realistic" is what a well-implemented stack achieves in the field with real cards and real servers. --- ## 1. Link-by-link table ### 1.1 Card and source interfaces | Interface | Raw line rate | Encoding / protocol payload | Real cards (vendor-measured seq. read) | **In PoppyUp** (what limits it) ||---|---|---|---|---|| CFexpress Type B 4.0 (PCIe Gen4 ×2, NVMe) | 2 × 16 GT/s = 32 Gb/s | 128b/130b + TLP ≈ 3.5–3.7 GB/s | 3.4–3.7 GB/s (Sony Tough G 4.0, ProGrade Cobalt 4.0, Lexar Diamond) | **~1.65 GB/s** — negotiates to **Gen3 ×2** at the RK3588 root port (2 × 8 GT/s = 15.75 Gb/s payload ≈ 1.97 GB/s theoretical, 82–85 % delivered with NVMe QD ≥ 8). Card capability is 2× our root port; see §4.1 why this is acceptable. || CFexpress Type B 2.0 (Gen3 ×2) | 16 Gb/s | ≈ 1.97 GB/s | 1.5–1.8 GB/s | ~1.5–1.7 GB/s — **card-limited** || CFexpress Type A 4.0 (Gen4 ×1) | 16 Gb/s | ≈ 1.8 GB/s | 1.6–1.8 GB/s (Sony CEA-G 4.0, Nextorage) | **~850 MB/s** — Gen3 ×1 behind ASM2812 (985 MB/s theoretical) || CFexpress Type A 2.0 (Gen3 ×1) | 8 Gb/s | ≈ 985 MB/s | 700–900 MB/s | 700–850 MB/s — card-limited || SD UHS-II | FD156: 1.56 Gb/s per lane × 2 lanes (full duplex) → 156 MB/s each direction; HD312: both lanes one direction → 312 MB/s | ≈ 300 MB/s (HD312 mode) | 270–300 MB/s (Sony SF-G, ProGrade V90, Angelbird V90, Lexar 2000x) | **~280–300 MB/s** — GL9755 in HD312; **card-limited**; Gen3 ×1 lane not a factor || SD UHS-I (SDR104) | 104 MB/s bus | ≈ 100 MB/s | 90–100 MB/s (170–200 MB/s only in proprietary DDR200 mode, not supported) | ~90–100 MB/s — bus-limited || UHS-III | 624 MB/s | — | **No cards exist.** Spec published 2017, zero commercial cards. | Not supported; nothing lost || SD Express 7.x / 8.x | Gen3 ×1 / Gen4 ×1 / Gen3 ×2 | 985 MB/s / 1.97 GB/s | A handful of cards (SanDisk, Lexar, Samsung, ADATA); one or two cameras | Not supported in host mode; **cards fall back to UHS-I (~100 MB/s)**. Footprint-compatible GL9767 upgrade path if the market appears. || microSD UHS-I (SDR104) | 104 MB/s | ≈ 100 MB/s | 90–100 MB/s | **~90–100 MB/s** — GL9750, bus-limited || CFast 2.0 (SATA III) | 6 Gb/s | 8b/10b → 600 MB/s, AHCI ≈ 550 MB/s | 500–550 MB/s (SanDisk Extreme Pro, Angelbird AV Pro CF) | **~480–550 MB/s — card-limited.** ASM1064 sits on a Gen3 ×1 ASM2812 port (985 MB/s), so the lane is not a factor; ASM1064's AHCI DMA engine tops out near 550 MB/s on a single port. || External SSD on Port B (USB 3.2 Gen2, UAS) | 10 Gb/s | 128b/132b + UAS ≈ 1.1 GB/s | Samsung T7/T9 950–1 050 MB/s; Blackmagic-class 900+ | **~900 MB/s** — ASM3142 on Gen3 ×2 (1.97 GB/s upstream, not limiting); SSD-limited || Internal NVMe (Pro, M.2 2280, Gen3 ×2) | 16 Gb/s | ≈ 1.97 GB/s | Any modern Gen3/Gen4 SSD writes > 2 GB/s sustained for tens of GB, then SLC-cache exhaustion drops some to 0.8–1.5 GB/s | **~1.6–1.7 GB/s** link-limited, then SSD-cache-limited on multi-hundred-GB copies. Choose a TLC drive with large dynamic SLC or a "Pro" class drive (WD SN770/SN850X-class sustained ≥ 1.4 GB/s). | *XQD is not in this table: it is unsupported (no driver, no licence, no USB-reader workaround — final, D10). An XQD card is physically insertable in the CFe B slot; firmware detects a non-NVMe PCIe device and rejects it with "XQD not supported" (`01-requirements.md` IF-006). That detection message is the only XQD behaviour in the product.* ### 1.2 SoC-internal paths | Path | Rate | Notes ||---|---|---|| RK3588 `pcie3x4` bifurcated → CFe B, Gen3 ×2 | ~1.65 GB/s delivered | Dedicated root port; no sharing. DMA into LPDDR4x (RK3588 LPDDR4x-4266 ×64 → ~34 GB/s theoretical, ~20 GB/s practical) — memory is not a factor. || RK3588 `pcie3x2` → ASM2812, Gen3 ×2 upstream | ~1.65 GB/s delivered, **shared** by CFe A, NVMe, Ethernet, SD, microSD, CFast, USB-SSD | Worst-case concurrency below. || USB 3.2 Gen2 Port B (ASM3142, Gen3 ×2 switch port) → tethered phone / USB cellular adapter | Link ≥ 40 MB/s | iPhone USB tethering is USB 2.0-class in practice (~30–40 MB/s, even on Pro models); Android phones and USB adapters up to ~100 MB/s. **Never the bottleneck** — the phone's or adapter's cellular uplink (2.5–25 MB/s, §1.4) is. || Gen2 ×1 spare ×2 (`pcie2x1l0`, `pcie2x1l2`) | ~400 MB/s payload each | Test headers; `pcie2x1l0` carried the v0.1 modem. || Gen2 ×1 → Wi-Fi 7 | ~400 MB/s payload | MT7925 2×2 160 MHz PHY peak 2.9 Gbps = 360 MB/s; realistic TCP ≤ 300 MB/s. Gen2 ×1 is marginally limiting only at ideal 6 GHz 160 MHz. Acceptable. || RK3588 USB3 OTG1 (dwc3, 5 Gbps) → Port A gadget | 500 MB/s payload; f_tcm (UAS) ~400–420 MB/s, f_mass_storage (BOT) ~350–380 MB/s | CPU-bound in the gadget stack at 5 Gbps; A76 core handles it. || Memory bandwidth | ~20 GB/s practical | Every byte crosses memory twice (DMA in, DMA/TX out) plus hashing passes; at 500 MB/s upload the memory system runs at < 10 %. | **Worst-case ASM2812 upstream concurrency (Pro SKU):** CFe A read (850 MB/s) + NVMe write during quick-copy of the *CFe A* card (850 MB/s) + Ethernet TX (500 MB/s) + SD read (300 MB/s) = 2.5 GB/s > 1.65 GB/s. In practice PCIe arbitration shares fairly and everything slows proportionally; the only user-visible effect is quick-copy from CFe A dropping to ~500 MB/s while a 5GbE upload runs. **CFe B is unaffected** because it has its own root port — which is precisely why it got the dedicated lanes. Quick-copy from CFe B to NVMe crosses both root ports (CFe B in via `pcie3x4`, NVMe out via `pcie3x2`) and runs at the full ~1.6 GB/s. ### 1.3 CPU budget (RK3588: 4 × Cortex-A76 @ 2.4 GHz + 4 × Cortex-A55 @ 1.8 GHz, ARMv8.2 Crypto Extensions) | Operation | Per-A76-core throughput (measured class, OpenSSL 3 / xxHash reference) | Cores needed at 500 MB/s ||---|---|---|| AES-128-GCM (TLS 1.3 record encryption) | ~1.8–2.2 GB/s | 0.25 || ChaCha20-Poly1305 (fallback cipher) | ~1.0–1.3 GB/s | 0.45 || SHA-256 (S3 `x-amz-checksum-sha256`, SigV4 payload hash) | ~1.0–1.5 GB/s | 0.4 || MD5 (S3 ETag verification, Drive `md5Checksum`) | ~0.65–0.75 GB/s | 0.7 || xxHash64 (local manifest) | > 5 GB/s (memory-bound) | 0.1 || exFAT + block layer + NVMe I/O + TCP stack overhead | — | ~0.4 || **Total, S3 with SHA-256 + xxHash64** | | **~1.5 A76 cores** (NFR-018 budget: ≤ 2) || **Total, S3 with MD5 ETag + SHA-256 + xxHash64** | | ~2.2 cores — acceptable (2.5 A76 + A55s remain) | **SFTP is the CPU-bound endpoint.** A single OpenSSH connection is single-threaded on both ends: with `aes128-gcm@openssh.com` on an A76 it tops out around 250–400 MB/s, and many SFTP servers (small VPS, NAS) are slower than the client. Firmware must open **4–8 parallel SFTP connections** (per-file or chunked with `sftp` extension `copy-data`/offset writes) to fill a 5GbE link. This is a firmware design constraint, not a hardware one. **Conclusion:** the A76 cluster has ~2× headroom at 500 MB/s. It would *not* have had headroom at 10GbE (1.1 GB/s → ~3.5 cores for S3 with SHA-256) — one of the reasons 5GBASE-T is final (D6, §4.4). ### 1.4 Network links | Link | Raw | TCP/IP payload (1500 MTU, TLS record overhead) | Realistic sustained S3 multipart upload from PoppyUp | Limiter ||---|---|---|---|---|| 5GBASE-T | 5 Gb/s | ~590 MB/s | **480–520 MB/s** with 8–16 concurrent 16–64 MB parts | TCP window/ramp on each part, TLS, per-connection server pacing || 2.5GBASE-T | 2.5 Gb/s | ~295 MB/s | 270–290 MB/s | link || 1000BASE-T | 1 Gb/s | ~118 MB/s | 105–115 MB/s | link || 100BASE-TX | 100 Mb/s | ~11.8 MB/s | 11 MB/s | link || Wi-Fi 7, 2×2, 6 GHz, 160 MHz, 3 m LOS to Wi-Fi 7 AP | 2.9 Gb/s PHY | ~1.9–2.4 Gb/s MAC → 240–300 MB/s | **200–280 MB/s** | airtime efficiency, Gen2 ×1 lane at the very top || Wi-Fi 7/6E, 2×2, 5/6 GHz, 80 MHz, typical venue AP at 10 m | 1.2 Gb/s PHY | 600–900 Mb/s | **75–110 MB/s** | contention, rate adaptation || Wi-Fi 6/5, 2.4 GHz, 20 MHz, congested venue | 287 Mb/s PHY | 30–100 Mb/s | **3–8 MB/s** | congestion; effectively unusable for media || *Cellular via the user's phone (USB tether on Port B or Wi-Fi hotspot) or a USB cellular adapter — the rows below are what that phone/adapter delivers; PoppyUp has no modem of its own:* | | | | || 5G NR sub-6 SA/NSA, good C-band cell (US, urban, close to site) | — | 100–200 Mb/s UL | **12–25 MB/s** | cell UL scheduling, phone power headroom || 5G NR sub-6, typical (US/EU urban & suburban) | — | 20–80 Mb/s UL | **2.5–10 MB/s** | operator UL allocation (UL is typically ⅓–⅕ of DL), TDD UL/DL ratio (n77/n78 is ~25–30 % UL slots), UE transmit power (23 dBm) || LTE, typical (phones fall back automatically) | — | 10–30 Mb/s UL | 1.5–4 MB/s | as above || LTE, rural / edge of cell | — | 2–15 Mb/s UL | **0.25–2 MB/s** | path loss, single-layer UL || Phone **Wi-Fi hotspot** instead of USB tether (same cell) | Wi-Fi 5/6 hotspot, 80 MHz | — | 85–95 % of the rows above | hotspot Wi-Fi hop adds ~5–15 % overhead; phones thermally throttle after ~20–30 min of sustained TX (radio + hotspot). **USB tether avoids the Wi-Fi hop** and charges the phone from Port B. | **Latency effects.** 5G RTT of 30–60 ms (LTE 50–100 ms), plus a few ms for the USB tether or ~5–10 ms for a hotspot hop, matters for TCP ramp on every new part. Firmware must keep 4–8 parts in flight even at 10 MB/s so that a single connection stall (handover, cell reselection, phone screen-lock hiccup) does not idle the phone's radio. Chunk size on metered/tethered links should drop to 8–16 MB so that a lost connection re-sends little (FR-004). **Why cellular uplink is so far below the headline number.** The ~1 Gbps 5G uplink figure quoted for phones and modems assumes 100 MHz of n77/n78, 2 UL layers, 256-QAM, full UL slot allocation, and near-cell-centre SINR. Operators deploy TDD frames that give the uplink ~25–30 % of slots; UL MIMO 2-layer is rarely scheduled; UE power (23 dBm, Power Class 3) limits MCS beyond a few hundred metres; and the aggregate UL of the sector is shared. Speedtest medians for 5G uplink in the US in 2025–26 sit in the 15–35 Mbps range; 90th-percentile users see 80–150 Mbps. This is why a built-in modem was dropped in v0.2 (ADR §14): it would have delivered the same uplink as the phone already in the user's pocket, at ~$146 of BOM and a carrier-certification programme. The honest promise is "uploads over the cellular you already carry, with the phone charging while it works" — not a speed figure. ### 1.5 Endpoint and Internet-side limits | Endpoint | Per-connection practical rate | Aggregate limits | Implication ||---|---|---|---|| Amazon S3 / R2 / B2 / Wasabi / MinIO | 50–100 MB/s per TCP connection (TLS, server pacing) | 3 500 PUT/s per prefix (S3); effectively unlimited aggregate | Use multipart with **8–16 concurrent parts**, 16–64 MB parts (5 GB max part, 10 000 parts max → ≥ 100 MB parts for objects > 1 TB) || Google Drive (resumable upload API) | 20–60 MB/s per file session | 750 GB/day per user upload quota; per-user request quotas | Upload several files concurrently; **a 1 TB card cannot finish in one day on a standard Google account** — surface the quota to the user || Dropbox (upload sessions) | 20–60 MB/s per session; 150 MB append chunks | Rate limits per app; team storage | Concurrent sessions; use `upload_session/append_v2` batching || SFTP | 30–150 MB/s per connection depending on server CPU and cipher | Server CPU / disk | 4–8 connections; prefer `aes128-gcm` or `chacha20-poly1305` || Venue Internet uplink (the real ceiling behind Ethernet/Wi-Fi) | — | Studio/post-house 1–10 Gb/s; office 100 Mb/s–1 Gb/s; hotel 20–100 Mb/s; location shoot with Starlink 10–40 Mb/s UL | **In most locations the venue uplink, not PoppyUp, is the limiter.** 5GBASE-T exists for the studio/post-house case. | --- ## 2. Per-mode bottleneck table Chain notation: source → … → sink. **Bold** = the single limiting element. | Mode | Chain | Rates along chain | **Limiter** | Delivered ||---|---|---|---|---|| Standalone — Ethernet 5GbE, CFe B, S3 | CFe B card (3.5 GB/s) → Gen3 ×2 (1.65) → DDR → CPU hash+TLS (≥ 1.2 GB/s avail.) → RTL8126 (0.59) → **5GBASE-T / venue uplink** | 3 500 / 1 650 / 1 200 / 590 / 500 | **Network** | 480–520 MB/s || Standalone — Ethernet 1GbE venue | as above → **1000BASE-T** | … / 118 | **Network** | 105–115 MB/s || Standalone — tethered phone on Port B, CFe B, S3 | CFe B (1.65 GB/s) → CPU → ASM3142 → USB (iPhone ~40 MB/s, Android/adapter ~100) → phone / USB adapter → **its NR/LTE uplink** | 1 650 / … / 40–100 / 2.5–25 | **Phone's cellular uplink** | 2.5–25 MB/s || Standalone — Wi-Fi STA to phone hotspot | CFe B → CPU → MT7925 → hotspot Wi-Fi (~30–60 MB/s) → phone → **its NR/LTE uplink** | 1 650 / … / 30–60 / 2–22 | **Phone's cellular uplink** (−5–15 % hotspot overhead) | 2–22 MB/s || Standalone — Wi-Fi 7, ideal | CFe B → CPU → Gen2 ×1 (400) → MT7925 → **6 GHz 160 MHz air** → AP → venue uplink | 1 650 / 400 / 200–280 | **Air interface** (then venue uplink) | 200–280 MB/s || Standalone — Wi-Fi, typical venue | … → **80 MHz shared channel** | 75–110 | **Air interface / contention** | 75–110 MB/s || Standalone — SD UHS-II, any link ≥ 2.5GbE | **SD card** (300) → GL9755 → Gen3 ×1 (985) → … → 2.5GbE (295) | 300 / 985 / 295 | **Card ≈ 2.5GbE tie**; on 5GbE the card | 270–295 MB/s || Standalone — CFast, 5GbE | **CFast card** (500–550) → ASM1064 (550) → Gen3 ×1 (985) → … → 5GbE (590→500) | 550 / 550 / 985 / 500 | **Card ≈ 5GbE tie** | 480–500 MB/s || Standalone — microSD | **microSD card** (95) | 95 | **Card** | ~90–100 MB/s || Host — Path 1 (Pro, RO default), USB4 Mac/PC/iPad Pro | **CFe B card** (3.4–3.7 GB/s) → PI3DBS16412 → Gen4 ×2 (3.9 GB/s) → ASM2464PD → USB4 40 Gb/s PCIe tunnel (~3.2–3.4 GB/s) → host NVMe driver | 3 500 / 3 900 / 3 300 | **Card ≈ USB4 tunnel tie** | **2.8–3.2 GB/s** || Host — Path 1 (Pro, RO default), USB 3.2 Gen2 host (iPhone 15/16/17 Pro, TB3-less PC) | CFe B (3.5 GB/s) → ASM2464PD in **UAS fallback (10 Gb/s)** → host UAS | 3 500 / 1 000 | **USB 3.2 Gen2** | **900–1 000 MB/s** || Host — Path 2 (all SKUs, RO default), SoC gadget, any card, USB 3.x host | card (≤ 1.65 GB/s) → SoC → **dwc3 5 Gb/s UAS gadget** → host | ≤ 1 650 / 400 | **SoC USB 3.0 (5 Gbps) gadget** | **380–420 MB/s** || Host — Path 2, USB 2.0 iPhone (non-Pro) | card → SoC → dwc3 → **USB 2.0 (480 Mb/s)** | … / 40 | **iPhone's USB 2.0 port** | **35–40 MB/s** || Host — Path 1 into a USB 2.0 iPhone | ASM2464PD falls back to USB 2.0 BOT | 40 | **iPhone's USB 2.0 port** | 35–40 MB/s (identical to Path 2; Path 1 adds nothing for non-Pro iPhones) || SSD ingest — Port B → S3 over 5GbE | **SSD** (950) → ASM3142 10 Gb/s (1 000) → Gen3 ×2 shared (1 650) → CPU → **5GbE** (590→500) | 950 / 1 000 / 1 650 / 500 | **Network** | 480–520 MB/s || Quick copy — CFe B → NVMe (Pro) | CFe B (1.65 read via `pcie3x4`) → DDR → **NVMe write via `pcie3x2` (1.65)** → SSD sustained (≥ 1.4) | 1 650 / 1 650 / 1 400+ | **Gen3 ×2 NVMe link / SSD sustained write** | **1.4–1.6 GB/s** || Quick copy — CFe A → NVMe (Pro) | CFe A (850) → **shared `pcie3x2` both directions** (850 in + 850 out = 1.7 of 1.65) → NVMe | 850 / 1 650 shared | **Shared switch upstream** | ~750–800 MB/s || Buffer-to-NVMe then upload (network down → up) | NVMe read (1.65) → … → **network** | | **Network** | as network | --- ## 3. Worked examples — time to move a card Assumes sustained realistic rates from §1–2; no per-file overhead (adds 1–5 % for thousands of small stills; negligible for video). | Path | Rate | 256 GB | 1 TB | Notes ||---|---|---|---|---|| Card → PoppyUp internal read (CFe B, Gen3 ×2) | 1 650 MB/s | 2.6 min | 10 min | Floor for anything downstream || Quick copy CFe B → NVMe (Pro) | 1 500 MB/s | 2.8 min | 11 min | Card back in the shooter's hand || Host Path 1, USB4 Mac (Pro) | 3 000 MB/s | 1.4 min | 5.6 min | Card-limited; the Mac powers the device over Port C (PD sink, Pro — D7), so session length is not battery-limited || Host Path 1, iPhone Pro (USB 3.2 Gen2) (Pro) | 950 MB/s | 4.5 min | 18 min | Device on its own battery (iPhone is not a power source) || Host Path 2, SoC gadget (any card, Mac/PC/iPhone Pro) | 400 MB/s | 11 min | 42 min | || Host, iPhone non-Pro (USB 2.0) | 38 MB/s | 1.9 h | 7.3 h | Phone-limited; unavoidable || Upload, 5GBASE-T to S3 (studio) | 500 MB/s | 8.5 min | 33 min | Battery: ~0.55 h of 4.4 h used per TB || Upload, 2.5GBASE-T | 280 MB/s | 15 min | 60 min | || Upload, 1000BASE-T | 110 MB/s | 39 min | 2.5 h | Most common wired case || Upload, Wi-Fi 7 ideal | 250 MB/s | 17 min | 67 min | || Upload, typical venue Wi-Fi | 90 MB/s | 47 min | 3.1 h | || Upload, 100 Mb/s venue uplink | 11 MB/s | 6.5 h | 25 h | Venue-limited regardless of link type || Upload, phone/adapter on 5G, good C-band cell (USB tether or hotspot) | 18 MB/s | 4.0 h | 15.4 h | 1 TB exceeds one battery (8.3 h hotspot / 4.1 h tether charging the phone at 1.5 A) → needs PD; the phone needs power too || Upload, phone/adapter on 5G, typical | 6 MB/s | 11.9 h | 46 h | Two–six battery charges or external power for device and phone || Upload, phone on LTE, rural | 1 MB/s | 71 h | 12 days | Selects-only workflow; no hardware (ours or a built-in modem) can fix this | **Reading the table.** The ratio between the internal read rate and the typical 5G uplink of the user's phone is 1 650 / 6 ≈ **275×**; against rural LTE, ~1 650×. This is the central UX fact of the product, and it is unchanged by removing the built-in modem — the uplink was always the phone-class cellular uplink, whoever owns the radio. Over a tethered or hotspot phone, PoppyUp is a *background* uploader that runs for hours on a cart or a desk (charging the phone from Port B as it goes; a bag is for transport only — ADR §1, D2), and the firmware must let the user prioritise files (selects, proxies, low-res first) rather than blindly walking the directory. Over studio Ethernet it is a *foreground* tool that finishes a card in minutes. --- ## 4. Design conclusions ### 4.1 Why Gen3 on the card side is not a real compromise in standalone mode CFexpress 4.0 Type B cards run at Gen4 ×2 (3.5–3.7 GB/s). Our RK3588 root port is Gen3 ×2 (~1.65 GB/s delivered). That is a 2× haircut on paper. It is irrelevant for the primary function because: 1. The fastest network we ship (5GBASE-T) drains at ~500 MB/s — 3.3× *below* our Gen3 ×2 read rate. The card link would have to be slower than ~600 MB/s before it became the bottleneck on any network path.2. The only internal consumer that could use > 1 GB/s is the optional NVMe quick copy, and it is itself limited by a Gen3 ×2 NVMe link and by SSD sustained-write behaviour to ~1.4–1.6 GB/s.3. Going Gen4 would require a Gen4-capable root (no RK3588; i.MX 95 and QCS6490 are Gen3 too) or a Gen4 switch (Microchip Switchtec PFX/PM40028 class, 5–8 W, $60+), for zero standalone benefit. Where Gen4 *does* matter — a human waiting at a Mac for a card to offload — we bypass the SoC entirely (Path 1) and give the host the card's native Gen4 ×2 link through the ASM2464PD. That is exactly the silicon inside every current USB4 CFexpress 4.0 reader, so we inherit their performance and their compatibility history. ### 4.2 Why USB4 pass-through matters only for host mode — and why it is worth a port on the Pro SKU Path 1 delivers 2.8–3.2 GB/s to USB4 hosts and 0.9–1.0 GB/s to iPhone Pro. Path 2 (SoC gadget) delivers 0.4 GB/s to both. For a 1 TB card that is 6 min vs 42 min on a Mac and 18 min vs 42 min on an iPhone Pro. Professional users benchmark readers; an $80 USB4 reader beating the device's reader mode by 7× would define the product's reputation in reviews even though reader mode is secondary. The cost is one IP67 USB-C receptacle, the ASM2464PD (~$12–15), a Gen4 ×2 mux (~$3), a PD sink controller and VBUS priority mux (~$3–4, verify), and 10-layer low-loss routing on ~60 mm of trace. Restricting Path 1 to the CFe B slot (the top-priority media) keeps the PCIe topology simple (one mux, no second switch) and avoids the USB 3.2-fallback limitation of the bridge (it can present exactly one NVMe device). **Where the host's bottleneck actually is (D7).** When the user offloads *through a host app* — the iPhone or Mac app pulling files from PoppyUp and pushing them to the cloud — the host's own internet link (hotel Wi-Fi, the phone's cellular uplink, §1.4–1.5) is the bottleneck, not the USB hop: Port A's ~380 MB/s (Path 2) already outruns any host uplink by 10–100×, so app-driven cloud upload needs nothing more than Port A. Port C's value is confined to **fast local copies** to the host's own SSD (the 6-min-per-TB case above). That is why Port C is **Pro SKU only** (depopulated on Base, same PCB), why Base is fully validated and shippable without it, and why its schedule is decoupled from the Base launch (ADR §10, §12). Both paths present the card **read-only by default** (D8); on Port C, enforcement is layered — NVMe namespace write protection where the card supports it, bridge write-protect in UAS fallback, otherwise an explicit per-session consent prompt (`02-system-architecture.md` §4.10). Read-only enforcement has no effect on the read rates in this document. **Power in a Port C session (D7).** On the Pro SKU Port C is also a PD sink: a Mac attached on Port C (typically 15 W) powers the device through a priority mux into the charger (Port A has priority), so a USB4 reader session is not limited by the ADR §6.2 runtime row (6.4 h on battery) — it runs indefinitely. An iPhone on either port is never a power source; those sessions run on PoppyUp's battery. The alternative of putting Path 1 and Path 2 on a *single* connector was rejected: it needs a 20 GBd-per-lane (USB4 Gen3) 2:1 SuperSpeed mux ahead of both bridges plus PD-controller coordination to select the path before link training — parts are scarce, signal-integrity margin at 40 Gbps shrinks, and the failure modes are subtle. Two labelled ports are the robust answer for a v1 (ADR §13.1). ### 4.3 Where the headroom is, for years | Element | Today's need | Capacity in this design | Headroom ||---|---|---|---|| Card read (CFe B) | 500 MB/s (5GbE) | 1 650 MB/s | 3.3× || Host reader (Path 1, Pro) | card-limited | ~3.3 GB/s tunnel | tracks card generations through CFexpress 4.0; CFexpress "5.0"/Gen5 would exceed it || Ethernet | 100 Mb/s–1 Gb/s venues | 5 Gb/s | 5–50× over typical venue uplinks || Wi-Fi | Wi-Fi 6 venues (75–110 MB/s) | Wi-Fi 7 2×2 (200–280) | 2–3× || Cellular (via phone / USB adapter on Port B) | phone-class 5G NR / LTE uplink | n/a — the user's phone and USB adapters upgrade with the market (Rel-17 UL MIMO, 5G-Advanced) at no change to PoppyUp; USB 3.2 Gen2 on Port B outruns any of them | tracks the phone market, no board change || CPU | 1.5 A76 cores at 500 MB/s | 4 A76 + 4 A55 | ~2× at 5GbE (10GbE, which would have consumed the whole A76 cluster, was rejected — D6) || NVMe | 1.4–1.6 GB/s | Gen3 ×2 | matches CFe B internal read || Modularity | — | 2 M.2 sockets (Key-E Wi-Fi, M-key NVMe), reader daughterboard, 2× spare Gen2 ×1 + spare USB3 on test headers | new slot mixes / radios / a daughterboard without main-board re-spin (a built-in modem is *not* a population option — ADR §13 item 12) | ### 4.4 Ethernet: 5GBASE-T is final (D6) The Ethernet interface is the Realtek RTL8126 5GBASE-T MAC/PHY on one Gen3 ×1 switch lane — **final (D6, ADR §5)**; no 10GBASE-T footprint option or watch item is carried. Why: a 10GBASE-T PHY dissipates +2–4 W over the RTL8126's 1.9 W inside a sealed passive enclosure whose whole shutter-closed ceiling is ~10 W at 25 °C (ADR §2), S3 with SHA-256 at 1.1 GB/s would consume the entire A76 cluster (§1.3), and real-world venue uplinks (§1.5) rarely exceed 1 Gb/s — 5GBASE-T is already 5–50× headroom over them. The card side (CFe B at 1.65 GB/s) is unaffected either way. ### 4.5 Consequences for firmware (Phase 2), recorded here so hardware does not block them - Multipart/multi-connection everywhere (S3 8–16 parts, SFTP 4–8 connections, Drive/Dropbox several files) — the hardware provides the CPU for it.- Adaptive chunk size per link (64 MB Ethernet, 16 MB Wi-Fi, 8 MB metered/tethered — phone hotspot, USB tether, USB cellular adapter) — FR-004.- Priority-aware upload order on slow links (user-defined selects, smallest-first, proxies-first).- Per-part hashing pipelined with reads (double-buffered DMA) so the card read and the network TX overlap; no store-and-forward.- Metered/tethered links: keep 4–8 parts in flight; count bytes per link in the job engine (there are no modem counters to read) and cross-check against endpoint-reported bytes (FR-025). Surface the phone's trust/unlock prompt and the SSD-vs-tether exclusivity on Port B (FR-026, FR-030). --- ## 5. Data-path diagram with rates ```mermaidflowchart LR  subgraph CARDS["Top-edge media (read-only)"]    CFB["CFexpress B 4.0<br/>card 3.5 GB/s"]    CFA["CFexpress A 4.0<br/>card 1.8 GB/s"]    SD["SD UHS-II<br/>card 0.30 GB/s"]    USD["microSD UHS-I<br/>card 0.10 GB/s"]    CFAST["CFast 2.0<br/>card 0.55 GB/s"]  end  SSD["External SSD<br/>Port B, 0.95 GB/s"]   MUX{{"PI3DBS16412<br/>Gen4 x2 mux"}}  CFB -->|"Gen4 x2"| MUX  MUX -->|"A: Gen3 x2<br/>1.65 GB/s"| RP1["RK3588 pcie3x4<br/>root port"]  MUX -->|"B: Gen4 x2<br/>3.9 GB/s"| BR["ASM2464PD<br/>USB4 bridge"]  BR -->|"USB4 tunnel<br/>2.8-3.2 GB/s"| MAC["USB4 host (Mac/PC/iPad)<br/>Pro only, RO default<br/>Mac powers device (PD sink)"]  BR -.->|"USB 3.2 Gen2 UAS<br/>0.9-1.0 GB/s"| IPP["iPhone Pro"]   SW["ASM2812 switch<br/>upstream Gen3 x2<br/>1.65 GB/s shared"]  CFA -->|"Gen3 x1 0.85"| SW  SD -->|"GL9755"| SW  USD -->|"GL9750"| SW  CFAST -->|"ASM1064 SATA<br/>0.38-0.55"| SW  SSD -->|"ASM3142 10G"| SW  NVME["NVMe (Pro)<br/>Gen3 x2 1.6 GB/s"] <--> SW  SW --> RP2["RK3588 pcie3x2<br/>root port"]   RP1 --> CPU["RK3588 4xA76<br/>hash + TLS<br/>&gt;1.2 GB/s available"]  RP2 --> CPU   CPU -->|"Gen3 x1"| ETH["RTL8126 5GbE<br/>0.48-0.52 GB/s"]  CPU -->|"Gen2 x1"| WIFI["MT7925 Wi-Fi 7<br/>0.075-0.28 GB/s"]  SW -->|"ASM3142 10G<br/>USB 0.04-0.10 GB/s"| TETH["Port B tether<br/>phone or USB cellular adapter<br/>(user's device)"]  CPU -->|"dwc3 5 Gbps gadget"| PA["Port A host, RO default<br/>0.40 GB/s (USB3)<br/>0.04 GB/s (USB2)"]   ETH --> NET["Venue uplink<br/>0.01-1.2 GB/s"]  WIFI --> NET  WIFI -.->|"phone hotspot<br/>0.03-0.06 GB/s"| CELL  TETH --> CELL["Phone / adapter<br/>cellular uplink<br/>0.0025-0.025 GB/s"]  NET --> EP["Endpoint<br/>S3 / SFTP / Drive / Dropbox"]  CELL --> EP   style CELL fill:#ffe0e0,stroke:#c00  style NET fill:#fff3d0,stroke:#c80``` Red = the real-world bottleneck: the tethered or hotspot phone's (or USB adapter's) cellular uplink, 2.5–25 MB/s — not PoppyUp hardware. Amber = the usual bottleneck on wired/Wi-Fi paths (venue uplink). Everything inside PoppyUp runs at 0.4–3.2 GB/s; the USB tether link itself (0.04–0.10 GB/s) is still 2–40× above the cellular uplink it carries. --- ## 6. Measurements to take at PoC (closes the assumptions above) | # | Measurement | Pass ||---|---|---|| M1 | CFe B 4.0 cards from 3 vendors negotiate Gen3 ×2 on RK3588 root; `fio` seq read QD8 1 MB | ≥ 1.6 GB/s (NFR-014) || M2 | Same cards via ASM2464PD → M-series Mac (Pro path); record NWPC support (Identify Controller byte 531) per card for the Port C read-only mechanism | ≥ 2.8 GB/s; → iPhone 15 Pro ≥ 900 MB/s (NFR-015); NWPC table complete for the IF-001 card list (FR-045-A) || M3 | Hot re-route via PI3DBS16412 with REFCLK mux, 1 000 cycles | 0 link-training failures, 0 FS errors (FR-043) || M4 | S3 (MinIO on LAN) over RTL8126 5GbE with TLS + SHA-256, 100 GB | ≥ 480 MB/s, ≤ 2 A76 cores (NFR-010, NFR-018) || M5 | dwc3 f_tcm UAS gadget → Mac and iPhone 15 Pro | ≥ 380 MB/s (NFR-016); Files app browses exFAT || M6 | ASM2812 concurrency: CFe A read + NVMe write + Ethernet TX | Fair sharing; CFe B path unaffected || M7 | Tethered uplink: iPhone (`ipheth`) and Android (NCM/RNDIS) on Port B, plus Wi-Fi STA to the same phone's hotspot, iperf3 UL at 5 sites vs the phone's own speed test; 100 attach/detach cycles; phone charge current at 0.5/1.5/3 A | ≥ 90 % of phone (NFR-013); enumerate ≤ 10 s, 0 stuck states (FR-026); ILIM ±10 % (FR-030) || M8 | MT7925 STA+AP concurrent throughput | ≥ 60 % of STA-only (FR-028) || M9 | GL9755 HD312 with V90 cards; GL9750 SDR104; ASM1064 with CFast ≥ 480 MB/s, note trained link width/speed | per NFR-014 |