From 4e4f27c79dcf3e82c0c6a63b5bf1b1af3b35d569 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 22 Aug 2025 15:57:29 +0200 Subject: [PATCH 01/11] Fix: only create mixed slot UL TDU for more than 1 symbol For PUSCH, we need at least 2 symbols, so ensure when creating the TDA. --- openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c index 5fba6dcaaf..eeb317ae57 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c +++ b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c @@ -1115,7 +1115,6 @@ void nr_rrc_config_ul_tda(NR_ServingCellConfigCommon_t *scc, int min_fb_delay, i int N_dl1 = p1->nrofDownlinkSlots; int N_ul1 = p1->nrofUplinkSlots; - int N_dl2 = p2 ? p2->nrofDownlinkSlots : 0; int N_ul2 = p2 ? p2->nrofUplinkSlots : 0; int tdd_period_idx = get_tdd_period_idx(scc->tdd_UL_DL_ConfigurationCommon); int nb_periods_per_frame = get_nb_periods_per_frame(tdd_period_idx); @@ -1123,20 +1122,22 @@ void nr_rrc_config_ul_tda(NR_ServingCellConfigCommon_t *scc, int min_fb_delay, i // make TDA for the mixed slot long mixed_sliv = get_SLIV(NR_NUMBER_OF_SYMBOLS_PER_SLOT - ul_symb, ul_symb - 1); - if (ul_symb > 1 && (k2 <= N_dl1 || (p2 && N_ul2 == 0))) { + int mixed_min_ul_symb = 3; // need at least two symbols PUSCH + PUCCH + bool has_ul_mixed = ul_symb >= mixed_min_ul_symb; + if (has_ul_mixed && (k2 <= N_dl1 || (p2 && N_ul2 == 0))) { // UL TDA index 2 for mixed slot (TDD) (no pattern 2 and enough DL slots, or pattern2 only DL) tda = set_TimeDomainResourceAllocation(k2, mixed_sliv); // to be reached from suitable DL slot asn1cSeqAdd(&tda_list->list, tda); - } else if (ul_symb > 1 && !p2 && k2 > N_dl1) { // k2 > N_Dl1 + } else if (has_ul_mixed && !p2 && k2 > N_dl1) { // k2 > N_Dl1 // UL TDA for mixed slot without pattern 2 and less DL slots than k2 tda = set_TimeDomainResourceAllocation(nb_slots_per_period, mixed_sliv); // to be reached from last DL (mixed) slot, if any asn1cSeqAdd(&tda_list->list, tda); - } else if (ul_symb > 1 && N_ul2 > 0 && k2 > N_dl1) { + } else if (has_ul_mixed && N_ul2 > 0 && k2 > N_dl1) { // we have pattern 2 with UL, and less p1 DL slots than k2 tda = set_TimeDomainResourceAllocation(N_dl1 + N_ul2 + 1, mixed_sliv); asn1cSeqAdd(&tda_list->list, tda); } else { - AssertFatal(ul_symb == 0, "unhandled case of mixed slot: N_dl1 %d N_ul1 %d N_dl2 %d N_ul2 %d\n", N_dl1, N_ul1, N_dl2, N_ul2); + LOG_I(NR_RRC, "mixed slot has %d UL symbols, cannot create mixed slot TDA\n", ul_symb); } // make TDA for UL slots that are not reachable within k2/min_rxtxtime From 454f690272b7be1b038e6cf8ba0ecbb376de3c83 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 3 Sep 2025 17:57:27 +0200 Subject: [PATCH 02/11] UL TDA for SRS: set correct right k2 We need to set the different k2 values according to the number of UL slots, not all to the same k2. --- openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c index eeb317ae57..435ec2b6e8 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c +++ b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c @@ -1150,7 +1150,7 @@ void nr_rrc_config_ul_tda(NR_ServingCellConfigCommon_t *scc, int min_fb_delay, i tda = set_TimeDomainResourceAllocation(i, get_SLIV(0, 13)); asn1cSeqAdd(&tda_list->list, tda); if (do_SRS) { - tda = set_TimeDomainResourceAllocation(k2, get_SLIV(0, 12)); + tda = set_TimeDomainResourceAllocation(i, get_SLIV(0, 12)); asn1cSeqAdd(&tda_list->list, tda); } } From 11a561cb7b686df51107284c4da9484484fcc409 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 22 Aug 2025 15:57:48 +0200 Subject: [PATCH 03/11] Ensure that retransmission uses TDA as indicated Previously, the TDA reuse condition was wrong: for multiple TDAs with different k2, the symbol allocation might be the same, in which the previous logic was using the wrong TDA. Fix the condition, and insert an assert to ensure the allocated TDA is correct. --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index b08e703076..704d2017c7 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -1805,7 +1805,7 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac, new_sched.bwp_info = bwp_info; DevAssert(new_sched.ul_harq_pid == harq_pid); - bool reuse_old_tda = (retInfo->tda_info.startSymbolIndex == tda_info->startSymbolIndex) && (retInfo->tda_info.nrOfSymbols <= tda_info->nrOfSymbols); + bool reuse_old_tda = retInfo->time_domain_allocation == tda; if (reuse_old_tda && nrOfLayers == retInfo->nrOfLayers) { /* Check the resource is enough for retransmission */ const uint16_t slbitmap = SL_to_bitmap(retInfo->tda_info.startSymbolIndex, retInfo->tda_info.nrOfSymbols); @@ -1887,6 +1887,7 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac, fill_pdcch_vrb_map(nrmac, CC_id, &sched_ctrl->sched_pdcch, CCEIndex, sched_ctrl->aggregation_level, dci_beam_idx); // signal new allocation + DevAssert(new_sched.time_domain_allocation == tda); post_process_ulsch(nrmac, pp_pusch, UE, &new_sched); LOG_D(NR_MAC, "%4d.%2d Allocate UL retransmission RNTI %04x sched %4d.%2d (%d RBs)\n", From bd6180e362e5c0d89c6790f04123a8dc274d22d7 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 22 Aug 2025 17:13:50 +0200 Subject: [PATCH 04/11] UL TDA: ensure we reach Msg3 in all cases In at least the case of mu=1, min_rxtxtime=2 and DDDSU with no UL symbols (for ULSCH) in the mixed slot, the current state of code does not allow a UE to attach. This is because at mu=1, Msg3 is k2+delta, where k2=min_rxtxtime and delta(mu)=3. Prior, this special case was handled because we had a dedicated Msg3 TDA, which in most cases is not necessary (because the mixed slot allocates the DCI, and the following mixed slot has the UL grant). Add code that tries to ensure that we only add the Msg3 TDA in cases when we need it. Fixes: 961a646dc756 ("Remove dedicated Msg3 TDA") --- openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c index 435ec2b6e8..6b808eebfa 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c +++ b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c @@ -1115,6 +1115,7 @@ void nr_rrc_config_ul_tda(NR_ServingCellConfigCommon_t *scc, int min_fb_delay, i int N_dl1 = p1->nrofDownlinkSlots; int N_ul1 = p1->nrofUplinkSlots; + int N_dl2 = p2 ? p2->nrofDownlinkSlots : 0; int N_ul2 = p2 ? p2->nrofUplinkSlots : 0; int tdd_period_idx = get_tdd_period_idx(scc->tdd_UL_DL_ConfigurationCommon); int nb_periods_per_frame = get_nb_periods_per_frame(tdd_period_idx); @@ -1155,6 +1156,22 @@ void nr_rrc_config_ul_tda(NR_ServingCellConfigCommon_t *scc, int min_fb_delay, i } } } + + // for Msg3, an additional get_delta_for_k2(mu) is added to k2. + // check that any UL slot is reachable under this condition + // the below is designed to only hit specific (known) cases + // examples: DDDSU (no TDA in S), + int N_dl = max(N_dl1, N_dl2); + int delta = get_delta_for_k2(mu); + int k2_msg3 = k2 + delta; + if (nb_slots_per_period % k2_msg3 == 0 /* see example above */ + && k2_msg3 > N_dl /* otherwise, can always have a D that reaches U */ + && k2_msg3 > N_ul /* otherwise, can always have a D that reaches U */ + && !has_ul_mixed /* if mixed slot, even for DDDSU would reach */) { + /* reach next UL from mixed slot in previous period */ + tda = set_TimeDomainResourceAllocation(k2_msg3, get_SLIV(0, 13)); + asn1cSeqAdd(&tda_list->list, tda); + } } AssertFatal(tda_list->list.count <= 16, "cannot reach all UL slots with current TDD configuration\n"); From 67cb3f026dc5cada517c674304487243d72a8531 Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Fri, 5 Sep 2025 09:27:46 +0200 Subject: [PATCH 05/11] Save PUSCH information for each (re-)transmission Instead of only saving this information in the first transmission, also store it on each retransmission. This should ensure that if some information changes, we always relate to the last transmission. For instance, power control information might have changed, and should be considered in subsequent rounds, if necessary. It also simplifies code. Fixes: 6294ce715e4d ("Reorder pf_ul to process retransmission") --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 704d2017c7..eaec37b159 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -2421,16 +2421,11 @@ void post_process_ulsch(gNB_MAC_INST *nr_mac, post_process_pusch_t *pusch, NR_UE /* Statistics */ AssertFatal(cur_harq->round < nr_mac->ul_bler.harq_round_max, "Indexing ulsch_rounds[%d] is out of bounds\n", cur_harq->round); UE->mac_stats.ul.rounds[cur_harq->round]++; + /* Save information on MCS, TBS etc for the current initial transmission + * so we have access to it when retransmitting */ + cur_harq->sched_pusch = *sched_pusch; if (cur_harq->round == 0) { UE->mac_stats.ulsch_total_bytes_scheduled += sched_pusch->tb_size; - /* Save information on MCS, TBS etc for the current initial transmission - * so we have access to it when retransmitting */ - cur_harq->sched_pusch = *sched_pusch; - /* save which time allocation and nrOfLayers have been used, to be used on - * retransmissions */ - cur_harq->sched_pusch.time_domain_allocation = sched_pusch->time_domain_allocation; - cur_harq->sched_pusch.nrOfLayers = sched_pusch->nrOfLayers; - cur_harq->sched_pusch.tpmi = sched_pusch->tpmi; sched_ctrl->sched_ul_bytes += sched_pusch->tb_size; UE->mac_stats.ul.total_rbs += sched_pusch->rbSize; From 197492ae89ec858d874d11902af607a846e86ad6 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 5 Sep 2025 11:07:22 +0200 Subject: [PATCH 06/11] Add documentation on UL-heavy TDD patterns --- doc/MAC/mac-usage.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/doc/MAC/mac-usage.md b/doc/MAC/mac-usage.md index 6104519f82..13f633eb1a 100644 --- a/doc/MAC/mac-usage.md +++ b/doc/MAC/mac-usage.md @@ -38,7 +38,7 @@ The actual scheduler implementation can be found in functions `pf_dl()` and [`gNB_scheduler_ulsch.c`](../../openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c) (for UL), respectively. -## PDDCH aggregation level +## PDCCH aggregation level PDCCH aggregation level is selected using closed loop controller, where DL HARQ feedback is the controller feedback signal. It is used to increment `pdcch_cl_adjust` @@ -60,7 +60,7 @@ in aggregation level 2 which translates to `uess_agg_levels` set to `[0, 2, 0, Say we have 90% PDCCH success rate at aggregation level 1, `pdcch_cl_adjust` will stay at 0 for most of the time. 2 consecutive PDCCH failures will not result in increasing the aggregation level (because (0.05 + 0.05) * 4 = 0.4 which is closer to 0 than to 1). If PDCCH fails 3 times -in a row the aggregation level will change to 2 and hopefully back to 1 once more PDDCH successes +in a row the aggregation level will change to 2 and hopefully back to 1 once more PDCCH successes happen. ### Example 2 @@ -402,3 +402,13 @@ pattern2: { nrofUplinkSymbols2 = 0; }; ``` + +#### UL-heavy TDD patterns + +"UL-heavy TDD patterns", i.e., TDD patterns that have many UL slots are +supported. Examples for such patterns would be DSUUU or DDDSUUUUUU. + +Note that you should increase the aggregation level candidates as described in +[the corresponding section above](#pdcch-aggregation-level). This is because the +scheduler has to schedule multiple DCIs in a single DL slots for multiple UL +slots. As a suggestion, you could try `uess_agg_levels = [4, 2, 2, 0, 0]`. From 7c9a7ab3749e4af11a1728b7201c05db5a6873d7 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 10 Sep 2025 07:51:30 +0200 Subject: [PATCH 07/11] Reset sched_ul_bytes on BSR to tend to overestimation On BSR reception, reset sched_ul_bytes. This change means that we assume that no data is "in flight" for this UE at time of BSR reception, or, put differently, that we overestimate the buffer size at UE (in the worst case). To illustrate this, consider the following traces before/after this change. Before this change: Upon BSR reception, the estimated BSR of the UE is reset, but the gNB still accounts for data "in flight". It is visible that the calculated buffer size (estimated - scheduled) quickly goes to zero, and we don't use all resources, despite the buffer still being full. The maximum application throughput in this run was ~220Mbps. [NR_MAC] SHORT BSR at 773.19, est buf 300000 [NR_MAC] ULSCH/PUSCH: 774. 6 RNTI af8e UL sched 774. 9 PRB start 0:162 TDA 2 TBS 32797 est 300000 sched 152704 est BSR 147296 TPC 1 [NR_MAC] ULSCH/PUSCH: 774. 6 RNTI af8e UL sched 774.11 PRB start 0:162 TDA 4 TBS 7172 est 300000 sched 159876 est BSR 140124 TPC 1 [NR_MAC] ULSCH/PUSCH: 774.10 RNTI af8e UL sched 774.12 PRB start 0:162 TDA 0 TBS 32797 est 292845 sched 185501 est BSR 107344 TPC 1 [NR_MAC] ULSCH/PUSCH: 774.10 RNTI af8e UL sched 774.13 PRB start 0:162 TDA 2 TBS 32797 est 292845 sched 218298 est BSR 74547 TPC 1 [NR_MAC] ULSCH/PUSCH: 774.11 RNTI af8e UL sched 774.14 PRB start 0:162 TDA 2 TBS 32797 est 260117 sched 218298 est BSR 41819 TPC 1 [NR_MAC] ULSCH/PUSCH: 774.11 RNTI af8e UL sched 774.16 PRB start 0:162 TDA 4 TBS 7172 est 260117 sched 225470 est BSR 34647 TPC 1 [NR_MAC] ULSCH/PUSCH: 774.15 RNTI af8e UL sched 774.17 PRB start 0: 35 TDA 0 TBS 7172 est 220236 sched 185501 est BSR 34735 TPC 1 [NR_MAC] ULSCH/PUSCH: 774.15 RNTI af8e UL sched 774.18 PRB start 0:162 TDA 2 TBS 32797 est 220236 sched 218298 est BSR 1938 TPC 1 [NR_MAC] ULSCH/PUSCH: 774.16 RNTI af8e UL sched 774.19 PRB start 0: 10 TDA 2 TBS 2017 est 187508 sched 187518 est BSR -10 TPC 1 [NR_MAC] SHORT BSR at 774. 9, est buf 300000 [NR_MAC] ULSCH/PUSCH: 775. 0 RNTI af8e UL sched 775. 2 PRB start 0:162 TDA 0 TBS 32797 est 260117 sched 147549 est BSR 112568 TPC 1 [NR_MAC] ULSCH/PUSCH: 775. 0 RNTI af8e UL sched 775. 3 PRB start 0:162 TDA 2 TBS 32797 est 260117 sched 180346 est BSR 79771 TPC 1 [NR_MAC] ULSCH/PUSCH: 775. 1 RNTI af8e UL sched 775. 4 PRB start 0:162 TDA 2 TBS 32797 est 227389 sched 180346 est BSR 47043 TPC 1 [NR_MAC] ULSCH/PUSCH: 775. 1 RNTI af8e UL sched 775. 6 PRB start 0:162 TDA 4 TBS 7172 est 227389 sched 187518 est BSR 39871 TPC 1 [NR_MAC] ULSCH/PUSCH: 775. 5 RNTI af8e UL sched 775. 7 PRB start 0:162 TDA 0 TBS 32797 est 180353 sched 173174 est BSR 7179 TPC 1 [NR_MAC] ULSCH/PUSCH: 775. 5 RNTI af8e UL sched 775. 8 PRB start 0: 36 TDA 2 TBS 7298 est 180353 sched 180472 est BSR -119 TPC 1 After this change: The gNB resets the number of bytes "in flight" (sched). Thus, the calculated buffer is larger, and does not "run out" before a new BSR arrives (which still indicates the maximum). The UE is thus allocated all resources, but we might overestimate some resources. The maximum application throughput in this run was ~300Mbps, limited by MCS and not by estimated buffer size as in the previous case. [NR_MAC] SHORT BSR at 43. 3, est buf 300000 [NR_MAC] ULSCH/PUSCH: 43.15 RNTI d3ea UL sched 43.17 PRB start 0:162 TDA 0 TBS 36897 est 263180 sched 36897 est BSR 226283 TPC 1 [NR_MAC] ULSCH/PUSCH: 43.15 RNTI d3ea UL sched 43.18 PRB start 0:162 TDA 2 TBS 36897 est 263180 sched 73794 est BSR 189386 TPC 1 [NR_MAC] ULSCH/PUSCH: 43.16 RNTI d3ea UL sched 43.19 PRB start 12:150 TDA 2 TBS 33822 est 263180 sched 107616 est BSR 155564 TPC 1 [NR_MAC] ULSCH/PUSCH: 43.16 RNTI d3ea UL sched 44. 1 PRB start 0:162 TDA 4 TBS 7941 est 263180 sched 115557 est BSR 147623 TPC 1 [NR_MAC] ULSCH/PUSCH: 44. 1 RNTI d3ea UL sched 44. 3 PRB start 0:162 TDA 0 TBS 36897 est 173698 sched 25881 est BSR 147817 TPC 1 [NR_MAC] ULSCH/PUSCH: 44. 1 RNTI d3ea UL sched 44. 4 PRB start 0:162 TDA 2 TBS 36897 est 173698 sched 62778 est BSR 110920 TPC 1 [NR_MAC] ULSCH/PUSCH: 44. 1 RNTI d3ea UL sched 44. 6 PRB start 0:162 TDA 4 TBS 7941 est 173698 sched 70719 est BSR 102979 TPC 1 [NR_MAC] SHORT BSR at 43.13, est buf 300000 [NR_MAC] ULSCH/PUSCH: 44. 5 RNTI d3ea UL sched 44. 7 PRB start 0:162 TDA 0 TBS 36897 est 292079 sched 36897 est BSR 255182 TPC 1 [NR_MAC] ULSCH/PUSCH: 44. 5 RNTI d3ea UL sched 44. 8 PRB start 0:162 TDA 2 TBS 36897 est 292079 sched 73794 est BSR 218285 TPC 1 [NR_MAC] ULSCH/PUSCH: 44. 6 RNTI d3ea UL sched 44. 9 PRB start 0:162 TDA 2 TBS 36897 est 292079 sched 110691 est BSR 181388 TPC 1 [NR_MAC] ULSCH/PUSCH: 44. 6 RNTI d3ea UL sched 44.11 PRB start 0:162 TDA 4 TBS 7941 est 292079 sched 118632 est BSR 173447 TPC 1 [NR_MAC] ULSCH/PUSCH: 44.10 RNTI d3ea UL sched 44.12 PRB start 0:162 TDA 0 TBS 36897 est 213587 sched 39972 est BSR 173615 TPC 1 [NR_MAC] ULSCH/PUSCH: 44.10 RNTI d3ea UL sched 44.13 PRB start 0:162 TDA 2 TBS 36897 est 213587 sched 76869 est BSR 136718 TPC 1 --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index eaec37b159..ad685dba68 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -595,6 +595,7 @@ static int nr_process_mac_pdu(instance_t module_idP, /* Extract short BSR value */ ce_ptr = &pduP[mac_subheader_len]; sched_ctrl->estimated_ul_buffer = estimate_ul_buffer_short_bsr((NR_BSR_SHORT *)ce_ptr); + sched_ctrl->sched_ul_bytes = 0; LOG_D(NR_MAC, "SHORT BSR at %4d.%2d, est buf %d\n", frameP, slot, sched_ctrl->estimated_ul_buffer); break; @@ -603,6 +604,7 @@ static int nr_process_mac_pdu(instance_t module_idP, /* Extract long BSR value */ ce_ptr = &pduP[mac_subheader_len]; sched_ctrl->estimated_ul_buffer = estimate_ul_buffer_long_bsr((NR_BSR_LONG *)ce_ptr); + sched_ctrl->sched_ul_bytes = 0; LOG_D(NR_MAC, "LONG BSR at %4d.%2d, estim buf %d\n", frameP, slot, sched_ctrl->estimated_ul_buffer); break; From b283960637c6f598bc3a50651ac8ac6d353abae7 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 9 Sep 2025 10:40:01 +0200 Subject: [PATCH 08/11] Increase periodic BSR to 5ms: increase UL throughput In high throughput UL scenarios, at least with our configuration, the UE only sends Short BSR. The maximum is 300000 bytes, which is completely "scheduled away" after a couple of UL grants. Increase the periodic BSR to 5ms to get more BSR, which results in higher UL throughput. --- openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c index 6b808eebfa..2f020fbf4e 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c +++ b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c @@ -3006,7 +3006,7 @@ static NR_MAC_CellGroupConfig_t *configure_mac_cellgroup(const nr_mac_timers_t * NR_MAC_CellGroupConfig_t * mac_CellGroupConfig = calloc(1, sizeof(*mac_CellGroupConfig)); AssertFatal(mac_CellGroupConfig != NULL, "Couldn't allocate mac-CellGroupConfig. Out of memory!\n"); mac_CellGroupConfig->bsr_Config = calloc(1, sizeof(*mac_CellGroupConfig->bsr_Config)); - mac_CellGroupConfig->bsr_Config->periodicBSR_Timer = NR_BSR_Config__periodicBSR_Timer_sf10; + mac_CellGroupConfig->bsr_Config->periodicBSR_Timer = NR_BSR_Config__periodicBSR_Timer_sf5; mac_CellGroupConfig->bsr_Config->retxBSR_Timer = NR_BSR_Config__retxBSR_Timer_sf80; mac_CellGroupConfig->tag_Config = calloc(1, sizeof(*mac_CellGroupConfig->tag_Config)); mac_CellGroupConfig->tag_Config->tag_ToReleaseList = NULL; From bb378620e9f8d3bf7cabd3ad02ebf4ccec93670d Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 5 Sep 2025 11:23:25 +0200 Subject: [PATCH 09/11] Remove ulsch_max_frame_inactivity from CI configs The parameter is either set to 10 (the default, so not necessary), or to 0 forcing the gNB to schedule the UE all the time, which is only necessary in specific scenario, and here simply wrong. --- ci-scripts/conf_files/gnb-vnf.sa.band78.273prb.aerial.conf | 1 - ci-scripts/conf_files/gnb.sa.band254.u0.25prb.rfsim.ntn-leo.conf | 1 - ci-scripts/conf_files/gnb.sa.band254.u0.25prb.rfsim.ntn.conf | 1 - ci-scripts/conf_files/gnb.sa.band77.162prb.usrpn310.2x2.conf | 1 - ci-scripts/conf_files/gnb.sa.band77.273prb.usrpn310.2x2.conf | 1 - ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.neighbour.conf | 1 - 6 files changed, 6 deletions(-) diff --git a/ci-scripts/conf_files/gnb-vnf.sa.band78.273prb.aerial.conf b/ci-scripts/conf_files/gnb-vnf.sa.band78.273prb.aerial.conf index 585d639f9f..f26891d8f2 100644 --- a/ci-scripts/conf_files/gnb-vnf.sa.band78.273prb.aerial.conf +++ b/ci-scripts/conf_files/gnb-vnf.sa.band78.273prb.aerial.conf @@ -197,7 +197,6 @@ MACRLCs = ( tr_n_preference = "local_RRC"; pusch_TargetSNRx10 = 200; # 150; pucch_TargetSNRx10 = 200; #200; - ulsch_max_frame_inactivity = 10; dl_max_mcs = 28; ul_max_mcs = 28; } diff --git a/ci-scripts/conf_files/gnb.sa.band254.u0.25prb.rfsim.ntn-leo.conf b/ci-scripts/conf_files/gnb.sa.band254.u0.25prb.rfsim.ntn-leo.conf index 6b1ce70b01..8d71434f66 100644 --- a/ci-scripts/conf_files/gnb.sa.band254.u0.25prb.rfsim.ntn-leo.conf +++ b/ci-scripts/conf_files/gnb.sa.band254.u0.25prb.rfsim.ntn-leo.conf @@ -198,7 +198,6 @@ MACRLCs = ( num_cc = 1; tr_s_preference = "local_L1"; tr_n_preference = "local_RRC"; -# ulsch_max_frame_inactivity = 0; pusch_TargetSNRx10 = 150; pucch_TargetSNRx10 = 200; dl_max_mcs = 9; diff --git a/ci-scripts/conf_files/gnb.sa.band254.u0.25prb.rfsim.ntn.conf b/ci-scripts/conf_files/gnb.sa.band254.u0.25prb.rfsim.ntn.conf index 03ca88d01b..ceb689bf31 100644 --- a/ci-scripts/conf_files/gnb.sa.band254.u0.25prb.rfsim.ntn.conf +++ b/ci-scripts/conf_files/gnb.sa.band254.u0.25prb.rfsim.ntn.conf @@ -205,7 +205,6 @@ MACRLCs = ( num_cc = 1; tr_s_preference = "local_L1"; tr_n_preference = "local_RRC"; -# ulsch_max_frame_inactivity = 0; pusch_TargetSNRx10 = 150; pucch_TargetSNRx10 = 200; dl_max_mcs = 9; diff --git a/ci-scripts/conf_files/gnb.sa.band77.162prb.usrpn310.2x2.conf b/ci-scripts/conf_files/gnb.sa.band77.162prb.usrpn310.2x2.conf index 23a8b34c3a..b0b060362d 100644 --- a/ci-scripts/conf_files/gnb.sa.band77.162prb.usrpn310.2x2.conf +++ b/ci-scripts/conf_files/gnb.sa.band77.162prb.usrpn310.2x2.conf @@ -180,7 +180,6 @@ MACRLCs = ( tr_n_preference = "local_RRC"; pusch_TargetSNRx10 = 300; pucch_TargetSNRx10 = 300; - ulsch_max_frame_inactivity = 0; pusch_FailureThres = 100; ul_max_mcs = 28; } diff --git a/ci-scripts/conf_files/gnb.sa.band77.273prb.usrpn310.2x2.conf b/ci-scripts/conf_files/gnb.sa.band77.273prb.usrpn310.2x2.conf index 3c51a977d8..5928ea4452 100644 --- a/ci-scripts/conf_files/gnb.sa.band77.273prb.usrpn310.2x2.conf +++ b/ci-scripts/conf_files/gnb.sa.band77.273prb.usrpn310.2x2.conf @@ -175,7 +175,6 @@ MACRLCs = ( pusch_TargetSNRx10 = 270; pucch_TargetSNRx10 = 270; pusch_FailureThres = 1000; - ulsch_max_frame_inactivity = 0; ul_max_mcs = 25; } ); diff --git a/ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.neighbour.conf b/ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.neighbour.conf index 0808c4b43d..eebf6e644f 100644 --- a/ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.neighbour.conf +++ b/ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.neighbour.conf @@ -233,7 +233,6 @@ MACRLCs = ( tr_n_preference = "local_RRC"; pusch_TargetSNRx10 = 250; pucch_TargetSNRx10 = 200; - ulsch_max_frame_inactivity = 0; } ); From 13e9910e4e09e65ae5da53817047174804b27389 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 9 Sep 2025 10:46:00 +0200 Subject: [PATCH 10/11] Modify CI SA 60MHz 2x2 test to be DSUUU Update configuration and tweak iperf thresholds accordingly. Tune some parameters for good UL reception. --- .../gnb.sa.band77.162prb.usrpn310.2x2.conf | 13 ++++++++----- .../container_sa_n310_2X2_60MHz_quectel.xml | 14 +++++++------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/ci-scripts/conf_files/gnb.sa.band77.162prb.usrpn310.2x2.conf b/ci-scripts/conf_files/gnb.sa.band77.162prb.usrpn310.2x2.conf index b0b060362d..932699a83f 100644 --- a/ci-scripts/conf_files/gnb.sa.band77.162prb.usrpn310.2x2.conf +++ b/ci-scripts/conf_files/gnb.sa.band77.162prb.usrpn310.2x2.conf @@ -24,6 +24,7 @@ gNBs = pusch_AntennaPorts = 2; do_CSIRS = 1; do_SRS = 1; + uess_agg_levels = [4,2,0,0,0]; servingCellConfigCommon = ( { @@ -139,9 +140,9 @@ gNBs = # dl_UL_TransmissionPeriodicity # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 dl_UL_TransmissionPeriodicity = 5; - nrofDownlinkSlots = 2; + nrofDownlinkSlots = 1; nrofDownlinkSymbols = 6; - nrofUplinkSlots = 2; + nrofUplinkSlots = 3; nrofUplinkSymbols = 4; ssPBCH_BlockPower = -20; @@ -178,10 +179,12 @@ MACRLCs = ( num_cc = 1; tr_s_preference = "local_L1"; tr_n_preference = "local_RRC"; - pusch_TargetSNRx10 = 300; - pucch_TargetSNRx10 = 300; + pusch_TargetSNRx10 = 320; + pucch_TargetSNRx10 = 320; pusch_FailureThres = 100; - ul_max_mcs = 28; + ul_max_mcs = 28; + ul_bler_target_upper = 0.20; + ul_bler_target_lower = 0.10; } ); diff --git a/ci-scripts/xml_files/container_sa_n310_2X2_60MHz_quectel.xml b/ci-scripts/xml_files/container_sa_n310_2X2_60MHz_quectel.xml index b153952252..ab7188c023 100644 --- a/ci-scripts/xml_files/container_sa_n310_2X2_60MHz_quectel.xml +++ b/ci-scripts/xml_files/container_sa_n310_2X2_60MHz_quectel.xml @@ -22,7 +22,7 @@ --> TEST-SA-FR1-N310-2x2-60MHz - 60 MHz 2x2 TDD SA + 60 MHz 2x2 TDD SA DSUUU tasks 100000 @@ -114,8 +114,8 @@ Iperf - iperf (DL/200Mbps/UDP)(30 sec)(single-ue profile) - -u -b 200M -t 30 -R + iperf (DL/150Mbps/UDP)(30 sec)(single-ue profile) + -u -b 150M -t 30 -R matix-cn5g up2 25 @@ -124,8 +124,8 @@ Iperf - iperf (UL/180Mbps/UDP)(30 sec)(single-ue profile) - -u -b 180M -t 30 + iperf (UL/250Mbps/UDP)(30 sec)(single-ue profile) + -u -b 250M -t 30 matix-cn5g up2 10 @@ -147,8 +147,8 @@ matix ci-scripts/yaml_files/5g_sa_n310_2x2_60MHz oai-gnb - 10,100,100,100 - 10,100,100,100 + 15,100,100,100 + 20,100,100,100 From e2b3c1546e6b85535f260d2a3ef5df7b51fdbfb5 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 5 Sep 2025 11:29:08 +0200 Subject: [PATCH 11/11] Add TDD pattern config asserts Check that the number of slots in period/symbols in mixed slot conforms to what is prescribed by the spec. --- openair2/LAYER2/NR_MAC_COMMON/nr_mac_common_tdd.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common_tdd.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common_tdd.c index b9f41a64a3..922a0153d9 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common_tdd.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common_tdd.c @@ -138,6 +138,10 @@ static uint8_t set_tdd_bmap_period(const NR_TDD_UL_DL_Pattern_t *pattern, tdd_pe n_ul_slot, n_dl_symbols, n_ul_symbols); + AssertFatal(n_dl_symbols + n_ul_symbols < 14, + "number of mixed slot symbols must be smaller than 14: DL %d, UL %d\n", + n_dl_symbols, + n_ul_symbols); return total_slot; } @@ -174,6 +178,11 @@ static void config_tdd_patterns(const NR_TDD_UL_DL_ConfigCommon_t *tdd, frame_st num_of_patterns, nb_slots_p1, nb_slots_p2); + AssertFatal(nb_slots_p1 + nb_slots_p2 == fs->numb_slots_period, + "total number of slots must equal to %d: p1 %d + p2 %d\n", + fs->numb_slots_period, + nb_slots_p1, + nb_slots_p2); } /**