ruvnet/RuView · warning
ENOTSUP
ENOTSUP
Error message
veil: [blob-blocked] MU-MIMO group shuffle needs a vendor subcmd / firmware patch (TODO(hw))
What it means
This is an intentional, documented stub, not a fault. `veil_shuffle_mumimo_groups` fires on every NL80211_CMD_NEW_STATION/DEL_STATION event, but MU-MIMO group shuffling needs a vendor-specific nl80211 subcommand or patched WiFi MCU firmware that does not exist upstream for mt76/ath. The function deliberately logs on stderr and returns `-ENOTSUP` instead of faking success, per the comment and INTEGRATION.md §3.
Source
Thrown at firmware/privshield/openwrt/veil_shieldd.c:171
fprintf(stderr, "veil: [feasible/indirect] next sounding jitter = %u ms "
"(TODO(hw): apply via hostapd ctrl_iface)\n", ms);
return 0;
}
/* ---------------------------------------------------------------------- */
/* CONTROL 3 (MOSTLY BLOB-BLOCKED): MU-MIMO group shuffling. */
/* The MU group definition + steering matrices are computed and applied in */
/* the WiFi MCU firmware on mt76 (mt7915) and all ath1x parts. There is no */
/* generic nl80211 command to reshuffle MU groups. Only a vendor subcmd */
/* (NL80211_CMD_VENDOR) on a driver that chose to expose one could do it. */
/* ---------------------------------------------------------------------- */
static int veil_shuffle_mumimo_groups(struct veil_ctx *c) {
(void)c;
/* TODO(hw): requires NL80211_CMD_VENDOR + a driver-specific
* NL80211_ATTR_VENDOR_ID / _SUBCMD / _DATA that does not exist upstream
* for mt76/ath. Without a driver+firmware patch this is unreachable.
* See INTEGRATION.md §3. Left as an explicit no-op, not a fake success. */
fprintf(stderr, "veil: [blob-blocked] MU-MIMO group shuffle needs a "
"vendor subcmd / firmware patch (TODO(hw))\n");
return -ENOTSUP;
}
/* ---------------------------------------------------------------------- */
/* CONTROL 4 (BLOB-BLOCKED on commodity AP silicon): the keyed rotation. */
/* This is the actual VEIL transform — a keyed Givens rotation on the fine */
/* subspace of the compressed beamforming feedback (the phi/psi angles), */
/* or equivalently a unitary Q on the LTF spatial mapping. On mt76/ath the */
/* feedback report is generated and the precoder applied inside firmware, */
/* so userspace cannot edit it. This function shows WHERE the core plugs */
/* in for the platforms that CAN reach the buffer (openwifi FPGA datapath, */
/* Nexmon Broadcom patch) — it operates on a caller-supplied fine block. */
/* ---------------------------------------------------------------------- */
static int veil_apply_keyed_rotation(struct veil_ctx *c,
float *fine, size_t n) {
if (!fine || n < 2) return -EINVAL;
/* Pure, orthogonal, energy-preserving (the "not jamming" invariant). */View on GitHub (pinned to 4685618388)
Solutions
- Treat it as informational: no action is required and nothing is broken; the caller ignores the return value by design.
- Filter it from logs (`logread | grep -v 'blob-blocked'`) or rate-limit stderr if station churn makes it noisy.
- Only a vendor subcmd (NL80211_CMD_VENDOR) or an openwifi-style FPGA datapath can make this path real — see INTEGRATION.md §3 before promising the capability.
Example fix
/* before: logs on every station event */
(void)veil_shuffle_mumimo_groups(c);
/* after: rate-limit the expected ENOTSUP notice */
static time_t last_mumo;
if (time(NULL) - last_mumo > 60) { (void)veil_shuffle_mumimo_groups(c); last_mumo = time(NULL); } Defensive patterns
Strategy: fallback
Try / catch
/* caller already degrades gracefully by design */
int rc = veil_shuffle_mumimo_groups(c);
if (rc == -ENOTSUP) {
/* expected on mt76/ath: no vendor subcmd exists; skip, do not alert */
} else if (rc < 0) {
fprintf(stderr, "veil: mumimo shuffle rc=%d\n", rc);
} Prevention
- Exclude 'blob-blocked' stderr lines from alerting and dashboards.
- Rate-limit the notice if station churn makes logs noisy.
- Never present MU-MIMO shuffling as a working feature on mt76/ath — it is firmware-blocked by design.
When it happens
Trigger: Any client associating or leaving the AP while the daemon monitors MLME multicast events — i.e. normal operation. The message repeats on each membership change and the daemon continues running.
Common situations: Operators reading router logs who mistake the recurring notice for a malfunction; monitoring/alerting wired to stderr that pages on every line; CI running against a softAP.
Related errors
AI-assisted analysis of ruvnet/RuView@4685618388 (2026-08-16).
Data as JSON: /api/errors/508f5a7bf93b67b6.
Report an issue: GitHub.