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

  1. Treat it as informational: no action is required and nothing is broken; the caller ignores the return value by design.
  2. Filter it from logs (`logread | grep -v 'blob-blocked'`) or rate-limit stderr if station churn makes it noisy.
  3. 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

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.