-
-
Notifications
You must be signed in to change notification settings - Fork 25
mt7612u: a MediaTek backend, measured — is it in scope? #412
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
snokvist
wants to merge
12
commits into
OpenIPC:master
Choose a base branch
from
snokvist:feat/mt7612u-mediatek-backend
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
36d45ce
mt7612u: a MediaTek backend, measured but not wired in
snokvist 2142a5a
mt7612u: fix the defects under the measurements
snokvist c64975d
mt7612u: generate initvals.h instead of transcribing it
snokvist 2ac9b9a
mt7612u: portability fixes that stand on their own
snokvist 081f952
docs(mt7612u): record the offline tests and re-verify on hardware
snokvist a9cd156
mt7612u: a radiotap VHT bandwidth code is a width *and* a sub-channel
snokvist 62410fb
mt7612u: untrack a test binary that slipped past .gitignore
snokvist 5e85f7a
mt7612u: measure what the four bytes past MPDU_LEN actually are
snokvist 7be0e40
mt7612u: the 40 MHz path tunes a channel it was never asked for
snokvist eca657c
mt7612u: act on the Qodo review — five real, two not
snokvist 1b032b5
mt7612u: complete the subtree, and close the five deferred findings
snokvist 737b4c6
mt7612u: one TX ceiling, and four more from the re-review
snokvist File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| bringup | ||
| tests/api_link | ||
| tests/frame_shape | ||
| tests/field_macros | ||
| *.o | ||
| *.d | ||
| firmware/ | ||
| wrlog.txt | ||
| mculog.txt |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| # Standalone: this subtree is not reachable from the project's CMakeLists.txt. | ||
| # tests/api_link.c links against the public header alone, which is what keeps | ||
| # that an honest test of the exported surface. | ||
| CC ?= gcc | ||
| CFLAGS ?= -O2 -g -Wall -Wextra -Wno-unused-parameter | ||
| # -MMD -MP: without header deps, editing internal.h leaves stale objects with | ||
| # the old struct layout linked against new ones. That corrupts the device | ||
| # struct at runtime and presents as a wild pointer, not a build problem. | ||
| DEPFLAGS = -MMD -MP | ||
| LDLIBS = -lusb-1.0 -lpthread | ||
| LIBSRCS = $(wildcard *.c) | ||
| TESTS = tests/api_link tests/frame_shape tests/field_macros | ||
| SRCS = $(LIBSRCS) tools/bringup.c $(TESTS:=.c) | ||
| OBJS = $(SRCS:.c=.o) | ||
| LIBOBJS = $(LIBSRCS:.c=.o) | ||
| DEPS = $(OBJS:.o=.d) | ||
|
|
||
| all: bringup $(TESTS) | ||
|
|
||
| bringup: $(LIBOBJS) tools/bringup.o | ||
| $(CC) $(CFLAGS) -o $@ $^ $(LDLIBS) | ||
|
|
||
| # Links against the public header only, so a declaration with no definition | ||
| # is a link error here rather than a surprise at the first caller. | ||
| tests/api_link: $(LIBOBJS) tests/api_link.o | ||
| $(CC) $(CFLAGS) -o $@ $^ $(LDLIBS) | ||
|
|
||
| tests/frame_shape: $(LIBOBJS) tests/frame_shape.o | ||
| $(CC) $(CFLAGS) -o $@ $^ $(LDLIBS) | ||
|
|
||
| tests/field_macros: $(LIBOBJS) tests/field_macros.o | ||
| $(CC) $(CFLAGS) -o $@ $^ $(LDLIBS) | ||
|
|
||
| %.o: %.c | ||
| $(CC) $(CFLAGS) $(DEPFLAGS) -I. -Iinclude -c -o $@ $< | ||
|
|
||
| # No hardware and no privileges needed: safe to run anywhere. `bringup` is a | ||
| # dependency but is not run: nothing else compiles it, so without it here a | ||
| # change that breaks a gate ships and no test notices. | ||
| check: $(TESTS) bringup | ||
| @for t in $(TESTS); do ./$$t || exit 1; done | ||
|
|
||
| clean: | ||
| rm -f $(OBJS) $(DEPS) bringup $(TESTS) | ||
| -include $(DEPS) | ||
| .PHONY: all check clean |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,136 @@ | ||
| # src/mt7612u — MediaTek MT7612U | ||
|
|
||
| **Not reachable from `CMakeLists.txt` yet.** This subtree is a complete, | ||
| self-contained C library for the part — a public header, its own transport, no | ||
| dependency on `RtlAdapter` — plus the bring-up harness that produced every | ||
| measurement in `docs/mt7612u.md`. Wiring it in behind `IRtlDevice` is a | ||
| follow-up PR; nothing in the shipped library links against this today. | ||
|
|
||
| It builds and tests on its own: | ||
|
|
||
| ```sh | ||
| make -C src/mt7612u # -> src/mt7612u/bringup | ||
| make -C src/mt7612u check # offline tests: no hardware, no privileges | ||
| sudo ./src/mt7612u/bringup regs | ||
| ``` | ||
|
|
||
| Measurements, methods and limits: [`../../docs/mt7612u.md`](../../docs/mt7612u.md). | ||
|
|
||
| ## Layout | ||
|
|
||
| | file | what | | ||
| |---|---| | ||
| | `usb.c` | libusb transport: EP0 vendor register access, sync bulk, open/claim/reset | | ||
| | `async.c` | event thread, 16-deep RX ring, 32-slot TX pool | | ||
| | `mcu.c` | in-band MCU command framing (EP 8 out, EP 5 in, 4-bit sequence) | | ||
| | `fw.c` | ROM patch + ILM/DLM firmware upload | | ||
| | `eeprom.c` | 512-byte EEPROM: identity, TX power tables, RX gain | | ||
| | `init.c` | power-on, MAC initvals, mac_start/stop, EP-4 flush | | ||
| | `phy.c` | band/bandwidth/TX power registers, channel + calibration sequence | | ||
| | `tx.c` | TXWI + TXINFO construction | | ||
| | `rx.c` | RXWI parse, per-chain RSSI, rate decode | | ||
| | `radiotap.c` | `send_packet` / `send_packets` (USB chaining via `NEXT_VLD`) | | ||
| | `caps.c` | TSF, capability descriptor, ACK responder | | ||
| | `tools/bringup.c` | one subcommand per verified gate | | ||
| | `tests/` | offline tests (`make check`): public-API link, frame shapes | | ||
| | `initvals.h` | **generated** — see Provenance | | ||
|
|
||
| ## The receiver must never run undrained | ||
|
|
||
| Enabling MAC RX with nothing reading the bulk-IN endpoint wedges this part | ||
| *below* the USB level: `libusb_reset_device`, the sysfs `authorized` toggle | ||
| and rebinding the kernel driver all fail to recover it, and only a physical | ||
| replug does. So `mt_mac_start()` takes the receiver as an explicit argument, | ||
| `mt7612u_start()` enables RX only when `mt7612u_rx_start()` is already | ||
| running, and every gate that turns RX on starts the ring *first*. | ||
|
|
||
| ## Portability | ||
|
|
||
| Done here, because these are correctness issues regardless of compiler: | ||
|
|
||
| - `FIELD_PREP`/`FIELD_GET` no longer use `__builtin_ctz`. MSVC has no such | ||
| builtin, and its `_BitScanForward` takes an out-parameter, so it cannot | ||
| appear in a constant expression - which these must be, since `FIELD_PREP` | ||
| initialises static tables. `MT_CTZ` is a constant expression everywhere and | ||
| folds to one instruction. `tests/field_macros` checks it against the | ||
| builtin over all 32 single-bit and all 528 contiguous masks, and fails to | ||
| compile if it ever stops being constant-foldable. | ||
| - The shift macro was named `_SHIFT`. Leading underscore plus a capital is | ||
| reserved to the implementation in every scope. | ||
| - `<libusb.h>` (this project's spelling) is tried first, with the | ||
| distribution's `<libusb-1.0/libusb.h>` as the fallback. | ||
|
|
||
| **Not** done here: `async.c` uses pthreads and `usb.c` uses `nanosleep` / | ||
| `clock_gettime`. This project has no C threading or time shim - its shim is | ||
| the C++ standard library, which every other backend uses directly. Building | ||
| a throwaway C shim now would be deleted at integration, so those two files | ||
| keep POSIX until the subtree joins the build. They are the only two. | ||
|
|
||
| ## Firmware | ||
|
|
||
| Needs `mt7662_rom_patch.bin` and `mt7662.bin` from `linux-firmware` | ||
| (`/lib/firmware/mediatek/`, zstd-compressed on most distributions). Not | ||
| vendored here. Point `bringup` at a directory holding the decompressed pair: | ||
|
|
||
| ```sh | ||
| zstd -d /lib/firmware/mediatek/mt7662{,_rom_patch}.bin.zst -o firmware/ | ||
| ``` | ||
|
|
||
| ## Gates | ||
|
|
||
| Each subcommand is a hardware check that fails loudly, in dependency order: | ||
|
|
||
| ``` | ||
| regs registers + EEPROM round-trip chan channel set, 20 MHz | ||
| fw ROM patch + firmware + MCU ack tx inject at a fixed rate | ||
| init full bring-up + register-stream log rx monitor receive | ||
| caps capabilities, TSF, 40 MHz soak sync vs async throughput | ||
| pwr TX power vs the kernel's values ampdu aggregation A/B | ||
| gateg per-frame rate control ack ACK responder (needs a stimulus) | ||
| rtap send_packet / send_packets hop channel-switch cost | ||
| ``` | ||
|
|
||
| `make` here builds it as `./bringup`, which is what the hardware notes use. | ||
| The integration PR adds a CMake target for the same source, named | ||
| `mt7612uprobe` to sit beside `pcieprobe` / `kestrelprobe` / `rtl8733bprobe`, so | ||
| the chip-specific tool is not the one part of this backend that only a second | ||
| build system can produce. | ||
|
|
||
| `sweep`, `coding` and `vht` take a width as their fourth argument, in the | ||
| `MT7612U_BW_*` numbering — `0` = 20, `1` = 40, `2` = 80 MHz: | ||
|
|
||
| ```sh | ||
| ./bringup sweep 149 120 2 # VHT ladder at 80 MHz, control channel 149 | ||
| ``` | ||
|
|
||
| The witness has to listen at the same width (`DEVOURER_BW=40|80` for | ||
| devourer's own `rxdemo`). A 20 MHz receiver decodes *none* of an 80 MHz | ||
| frame — which makes it a good negative control and a misleading oracle. | ||
|
|
||
| At 80 MHz the HT ladder is skipped: 802.11n has no 80 MHz, so a rate word | ||
| naming `PHY=HT` with `BW=80` is not a wide HT frame, it is an unspecified one. | ||
|
|
||
| ## Provenance | ||
|
|
||
| Register sequences and descriptor layouts are derived from `openwrt/mt76` | ||
| (`mt76x2/`, `mt76x02*`, `usb.c`), BSD-3-Clause-Clear, Copyright (C) 2016 Felix | ||
| Fietkau, (C) 2018 Lorenzo Bianconi / Stanislaw Gruszka. Files carrying ported | ||
| sequences keep that notice. The tree is pinned as `reference/mt76` at commit | ||
| `be5ce79`. | ||
|
|
||
| `initvals.h` is **generated** from it, not transcribed: | ||
|
|
||
| ```sh | ||
| tools/extract_mt7612u_tables.py # regenerate | ||
| tools/extract_mt7612u_tables.py --check # byte-compare the checked-in file | ||
| ``` | ||
|
|
||
| The generator resolves the symbolic register names against `mt76x02_regs.h` and | ||
| evaluates the four `DEFAULT_PROT_CFG_*` macros, so a mistyped address cannot | ||
| survive as a plausible-looking number. It reproduces the previously hand-typed | ||
| table byte for byte, all sixty rows. | ||
|
|
||
| Two things here are **not** ports and were proven on air rather than copied: | ||
| the `MT_TXD_INFO_NEXT_VLD` USB chaining in `radiotap.c`, and the ACK responder | ||
| in `caps.c`. One thing copied from mt76 was **wrong** — see the TSF note in the | ||
| docs. | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.