Two changes on top of the initial MU-MIMO patch (commit 766d0a4):
1. CSI-parse fix in evaluate_cqi_report path: when maxMIMO_layers=1
(and thus ri_Restriction has only one bit set, ri_bitlen=0),
evaluate_ri_report was being skipped, leaving r_index=-1 which
trips the DevAssert(ri>=0) inside evaluate_cqi_report. Fix: when
ri_bitlen=0, pick the single allowed RI directly from the
restriction bitmap. Affects all three reportQuantity branches
(cri_RI_PMI_CQI, cri_RI_LI_PMI_CQI, cri_RI_CQI).
2. MU-MIMO scheduler: relaxed-orthogonality flag and broader
partner search:
- OAI_MU_MIMO_RELAXED=1 bypasses the strict (same-x1, x2-diff-2)
orthogonality test for testbed validation on rfsim where the
symmetric channel makes all UEs report identical PMI.
- Partner search now scans the full UE_sched (skipping leader and
already-paired entries) instead of only iterator+1; this finds
candidates regardless of PF position.
- Diagnostic LOG_W messages on partner-search entry and per-skip
reason (capped to 20 events to avoid log flood).
Findings on this w17 build with 6 UEs at 5Mbps DL each:
- Patch compiles, deploys, gNB does not crash, scheduler reaches
partner-search block on a fraction of slots.
- However eligible_others=0 in every observed partner-search entry:
PF puts only one UE in UE_sched per pf_dl call almost always,
even at cell saturation. The other attached UEs are skipped
earlier (likely HARQ pids pending feedback). So the partner
search has nothing to pair.
- Architectural conclusion: forcing concurrent multi-UE scheduling
on OAI's PF + finite-HARQ scheduler likely needs scanning
connected_ue_list (not just UE_sched), and may need broader
refactoring to pre-allocate slot resources for MU-MIMO pairs.
Adds opt-in MU-MIMO downlink co-scheduling to the production
proportional-fair scheduler (pf_dl). When OAI_MU_MIMO=1 is set in
the gNB process env, after the leader UE is allocated we look ahead
in the PF-sorted candidate list for an orthogonal-PMI partner. If
found and the partner can secure its own CCE+PUCCH, both UEs share
the same RB allocation with distinct DMRS CDM groups (port 1000 vs
port 1001) and are forced to the same MCS/TBS.
Orthogonality test (4-port Type I rank-1 codebook, N1=2, N2=1):
same x1 (same beam), x2 differing by 2 (co-phasing pairs {0,2} or
{1,3}). Both UEs must report rank-1.
Default OFF — set OAI_MU_MIMO=1 to enable. Builds on the upstream
FAPI/PHY MU-MIMO plumbing (commits 3707d52c95, 498d241d75,
9952996c5d) which carries antenna-port and DMRS-CDM metadata down
to the PHY transmit path.
Brings the O-RAN compliant antenna muting feature (originally introduced
on the 'new' branch) onto the latest upstream 2026.w17 tag.
Files added:
openair1/PHY/NR_TRANSPORT/nr_antenna_state.{c,h}
openair1/PHY/NR_TRANSPORT/nr_antenna_control.{c,h}
Files modified (integration hooks):
CMakeLists.txt, executables/nr-gnb.c
openair1/PHY/INIT/nr_init.c, openair1/PHY/defs_gNB.h
openair1/PHY/MODULATION/{beamforming.c,nr_modulation.h,nr_beamforming.c}
openair1/SCHED_NR/nr_ru_procedures.c
openair2/LAYER2/NR_MAC_gNB/mac_proto.h
openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_{primitives,dlsch,uci}.c
Conflicts resolved:
- defs_gNB.h: kept upstream's new headers + appended antenna_state.h
- nr_init.c: dropped reference to upstream-removed nr_srs_info init,
kept nr_init_antenna_state() call
- beamforming.c: upstream moved nr_beam_precoding into new file
nr_beamforming.c; nr_beam_precoding_with_muting added there with
upstream's signature (no slot param)
- nr_modulation.h: aligned _with_muting decl to upstream signature
- nr_ru_procedures.c: muting check applied around upstream's new
fft_shift in nr_feptx, and around per-port memcpy in nr_feptx_prec
- gNB_scheduler_uci.c: SINR-based MCS hint uses get_dl_nrOfLayers(NULL,
sched_ctrl, ...) since nrmac is not in scope at the call site
- mac_proto.h: get_dl_nrOfLayers signature updated to take gNB_MAC_INST*
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>