Commit 1cb82bae authored by Robert Schmidt's avatar Robert Schmidt

Merge remote-tracking branch 'origin/Mult_TDD_Pattern' into integration_2025_w05 (!2799)

Changes to support multiple TDD patterns

- Updated the configuration changes for 2 Patterns
- Update the TDD table configuration for NFAPI
- Added the tdd bitmap for the period
- Adapted the bitmap for UL/DL for the multi TDD pattern
- Updated the RACH procedure for multi TDD pattern
- Updated DL and UL scheduler for multi TDD pattern
parents 1e3e695f fcea7d9f
......@@ -66,7 +66,7 @@ gNBs =
initialULBWPsubcarrierSpacing = 1;
#rach-ConfigCommon
#rach-ConfigGeneric
prach_ConfigurationIndex = 98;
prach_ConfigurationIndex = 154;
#prach_msg1_FDM
#0 = one, 1=two, 2=four, 3=eight
prach_msg1_FDM = 0;
......@@ -133,11 +133,21 @@ gNBs =
# pattern1
# dl_UL_TransmissionPeriodicity
# 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
dl_UL_TransmissionPeriodicity = 6;
nrofDownlinkSlots = 7;
nrofDownlinkSymbols = 6;
nrofUplinkSlots = 2;
nrofUplinkSymbols = 4;
# ext: 8=ms3, 9=ms4
dl_UL_TransmissionPeriodicity = 8;
nrofDownlinkSlots = 3;
nrofDownlinkSymbols = 6;
nrofUplinkSlots = 2;
nrofUplinkSymbols = 4;
# pattern2
pattern2: {
dl_UL_TransmissionPeriodicity2 = 4;
nrofDownlinkSlots2 = 4;
nrofDownlinkSymbols2 = 0;
nrofUplinkSlots2 = 0;
nrofUplinkSymbols2 = 0;
};
ssPBCH_BlockPower = -25;
}
......
......@@ -21,8 +21,8 @@
-->
<testCaseList>
<htmlTabRef>TEST-SA-FR1-SC-FDMA-B200</htmlTabRef>
<htmlTabName>40 MHz TDD SA with SC-FDMA</htmlTabName>
<htmlTabRef>TEST-SA-FR1-SC-PATTERN2-FDMA-B200</htmlTabRef>
<htmlTabName>40 MHz TDD (pattern2) SA with SC-FDMA</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<TestCaseRequestedList>
300000
......@@ -101,7 +101,7 @@
</testCase>
<testCase id="230101">
<class>Deploy_Object</class>
<desc>Deploy gNB (TDD/Band78/40MHz/B200) with SC-FDMA in a container</desc>
<desc>Deploy gNB (TDD/pattern2/Band78/40MHz/B200) with SC-FDMA in a container</desc>
<yaml_path>ci-scripts/yaml_files/sa_sc_b200_gnb</yaml_path>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
......
......@@ -704,9 +704,12 @@ uint64_t from_nrarfcn(int nr_bandP, uint8_t scs_index, uint32_t nrarfcn)
return frequency;
}
int get_first_ul_slot(int nrofDownlinkSlots, int nrofDownlinkSymbols, int nrofUplinkSymbols)
/**
* @brief Get the slot index within the period
*/
int get_slot_idx_in_period(const int slot, const frame_structure_t *fs)
{
return (nrofDownlinkSlots + (nrofDownlinkSymbols != 0 && nrofUplinkSymbols == 0));
return slot % fs->numb_slots_period;
}
int get_dmrs_port(int nl, uint16_t dmrs_ports)
......
......@@ -122,6 +122,29 @@ typedef enum frequency_range_e {
FR2
} frequency_range_t;
#define MAX_NUM_SLOTS_ALLOWED 80 // up to numerology 3 (120 KHz SCS) is supported
enum slot_type { TDD_NR_DOWNLINK_SLOT, TDD_NR_UPLINK_SLOT, TDD_NR_MIXED_SLOT };
typedef struct tdd_bitmap {
enum slot_type slot_type;
uint8_t num_dl_symbols;
uint8_t num_ul_symbols;
} tdd_bitmap_t;
typedef struct tdd_period_config_s {
tdd_bitmap_t tdd_slot_bitmap[MAX_NUM_SLOTS_ALLOWED];
uint8_t num_dl_slots;
uint8_t num_ul_slots;
} tdd_period_config_t;
typedef struct frame_structure_s {
tdd_period_config_t period_cfg;
int8_t numb_slots_frame;
int8_t numb_slots_period;
int8_t numb_period_frame;
bool is_tdd;
} frame_structure_t;
typedef struct {
/// Time shift in number of samples estimated based on DMRS-PDSCH/PUSCH
int est_delay;
......@@ -219,7 +242,6 @@ void reverse_bits_u8(uint8_t const* in, size_t sz, uint8_t* out);
uint64_t from_nrarfcn(int nr_bandP, uint8_t scs_index, uint32_t dl_nrarfcn);
uint32_t to_nrarfcn(int nr_bandP, uint64_t dl_CarrierFreq, uint8_t scs_index, uint32_t bw);
int get_first_ul_slot(int nrofDownlinkSlots, int nrofDownlinkSymbols, int nrofUplinkSymbols);
int cce_to_reg_interleaving(const int R, int k, int n_shift, const int C, int L, const int N_regs);
int get_SLIV(uint8_t S, uint8_t L);
void get_coreset_rballoc(uint8_t *FreqDomainResource,int *n_rb,int *rb_offset);
......@@ -265,6 +287,8 @@ int get_smallest_supported_bandwidth_index(int scs, frequency_range_t frequency_
unsigned short get_m_srs(int c_srs, int b_srs);
unsigned short get_N_b_srs(int c_srs, int b_srs);
int get_slot_idx_in_period(const int slot, const frame_structure_t *fs);
#define CEILIDIV(a,b) ((a+b-1)/b)
#define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1))
......
......@@ -24,7 +24,9 @@
The following features are valid for the gNB and the 5G-NR UE.
* Static TDD, FDD
* Static TDD
- Multi TDD pattern supported refer [TDD Configuration](NR_SA_Multi_TDD_Pattern.md)
* Static FDD
* Normal CP
* Subcarrier spacings: 15 and 30kHz (FR1), 120kHz (FR2)
* Bandwidths: 10, 20, 40, 60, 80, 100MHz
......
......@@ -240,3 +240,115 @@ here, *also they pertain to the DU*, i.e., the scheduler.
options are 2, 4, 6, 8, 10, 12, 32; **32 is a Rel-17 features**)
* `num_ulharq` (default 16): as `num_dlharq` for UL (other valid option is 32;
**32 is i Rel-17 feature**)
## ServingCellConfigCommon parameters
The `gNBs` configuration section has a big structure `servingCellConfigCommon`
that has an influence on the overall behavior of MAC and L1. As the name says,
this structure is a flat representation of the ServingCellConfigCommon
structure, specified by 3GPP. Describing all of these parameters would be too
exhaustive; more information about the individual fields can be found in 3GPP
TS 38.331, section 6.3.2 "Radio resource control information elements".
Below is a description of some of these parameters.
### Frequency configuration
There are many parameters, such as `absoluteFrequencySSB`, etc., that have an
impact on the frequency used by the gNB. For more information, please check the
[corresponding document](../gNB_frequency_setup.md).
### TDD pattern configuration
The TDD configuration parameters allow to use one or two TDD patterns.
#### Single TDD pattern
Configure the TDD pattern through these options:
- `dl_UL_TransmissionPeriodicity`: Refers to the UL/DL slots periodicity for
the TDD pattern. See below for valid numbers.
- `nrofDownlinkSlots`: Refers to the number of consecutive DL slots in the TDD
pattern. The number of DL slots depends on the TDD period.
- `nrofDownlinkSymbols`: Indicates the number of consecutive DL symbols within
the special slot that follows the downlink slots in the TDD pattern. The
special slot is needed only to switch from DL to UL. The maximum number of
symbols in this slot is 14.
- `nrofUplinkSlots`: Refers to the number of consecutive UL slots in the TDD
pattern, depending on the desired TDD period.
- `nrofUplinkSymbols`: Indicates the number of consecutive UL symbols within
the special slot that follows the downlink slots in the TDD pattern. The sum
of downlink and uplink symbols should not exceed 14.
- `prach_ConfigurationIndex`: index for PRACH according to tables 6.3.3.2-2 to
6.3.3.2-4 in TS 38.211.
As an example, the below figure shows a single TDD pattern, consisting of 3 DL
slots, 1 mixed slots (with 10 DL, 2 guard, 2 UL symbols), and 1 UL slot.
![TDD Frame Structure](TDD_Frame_Structure.png)
To configure this pattern in the configuration file, use
```plaintext
#dl_UL_TransmissionPeriodicity 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10, 8=ms3, 9=ms4
dl_UL_TransmissionPeriodicity = 5;
nrofDownlinkSlots = 3;
nrofDownlinkSymbols = 10;
nrofUplinkSlots = 1;
nrofUplinkSymbols = 2;
```
The `dl_UL_TransmissionPeriodicity` is set to `5` (2.5ms). The above figure
shows two TDD periods over 5ms. The 10 ms frame period must be strictly
divisible by the sum of the TDD pattern periods.
#### Two TDD patterns
An optional `pattern2` structure is used to signal a TDD pattern 2.
In this case, the TDD pattern may have two extended values of 3 ms and 4 ms.
These values are standardized as `dl-UL-TransmissionPeriodicity-v1530`. For the
sake of simplicity of the gNB configuration file, we have extended the set of
`dl-UL-TransmissionPeriodicity` values to support the new TDD periods, as
explained in the table below. However, these values will later be encoded as
`dl-UL-TransmissionPeriodicity-v1530` to match the specifications.
| `dl_UL_TransmissionPeriodicity` | TDD period |
|---------------------------------|------------|
| 0 | 0.5 ms |
| 1 | 0.625 ms |
| 2 | 1 ms |
| 3 | 1.25 ms |
| 4 | 2 ms |
| 5 | 2.5 ms |
| 6 | 5 ms |
| 7 | 10 ms |
| 8 | 3 ms |
| 9 | 4 ms |
The 10 ms frame period must be strictly divisible by the sum of the TDD pattern
periods. For example, the 3 ms TDD pattern should be used with a second TDD
pattern of 2 ms. Additionally, the 4 ms TDD pattern should be used with a
second TDD pattern of 1 ms.
As an example, this configuration might be used, where the first TDD pattern is
followed by a second, consisting of 4 DL slots.
```
# pattern1
# dl_UL_TransmissionPeriodicity
# 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
# ext: 8=ms3, 9=ms4
dl_UL_TransmissionPeriodicity = 8;
nrofDownlinkSlots = 3;
nrofDownlinkSymbols = 6;
nrofUplinkSlots = 2;
nrofUplinkSymbols = 4;
# pattern2
pattern2: {
dl_UL_TransmissionPeriodicity2 = 4;
nrofDownlinkSlots2 = 4;
nrofDownlinkSymbols2 = 0;
nrofUplinkSlots2 = 0;
nrofUplinkSymbols2 = 0;
};
```
......@@ -25,6 +25,7 @@
#define NFAPI_MAX_NUM_CB 8
#define NFAPI_MAX_NUM_PRGS 1
#define NFAPI_MAX_NUM_BG_IF 1
#define NFAPI_MAX_NUM_PERIODS 8
// Extension to the generic structures for single tlv values
......@@ -436,7 +437,10 @@ typedef struct
typedef struct
{
nfapi_uint8_tlv_t tdd_period;//DL UL Transmission Periodicity. Value:0: ms0p5 1: ms0p625 2: ms1 3: ms1p25 4: ms2 5: ms2p5 6: ms5 7: ms10 8: ms3 9: ms4
/**DL UL Transmission Periodicity: for multiple TDD pattern,
* the value corresponds to the sum periodicity (3GPP TS 38.213, 11.1)
* Values: 0:ms0p5 1:ms0p625 2:ms1 3:ms1p25 4:ms2 5:ms2p5 6:ms5 7:ms10 8:ms20 */
nfapi_uint8_tlv_t tdd_period;
nfapi_nr_max_tdd_periodicity_t* max_tdd_periodicity_list;
} nfapi_nr_tdd_table_t;
......
......@@ -669,10 +669,6 @@ void pnf_nr_handle_config_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
{
nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, req.header.phy_id);
#if 0 // emulate set_config TLV reception (hard-code)
int tdd_return = set_tdd_config_nr(&req, 1, 7, 6, 2, 4);
#endif
if(phy)
{
if(phy->state != NFAPI_PNF_PHY_RUNNING)
......
This diff is collapsed.
......@@ -36,18 +36,16 @@
/*************** FUNCTIONS *****************************************/
/** \brief This function processes tdd dedicated configuration for nr
* @param frame_parms NR DL Frame parameters
* @param dl_UL_TransmissionPeriodicity periodicity
* @param nrofDownlinkSlots number of downlink slots
* @param nrofDownlinkSymbols number of downlink symbols
* @param nrofUplinkSlots number of uplink slots
* @param nrofUplinkSymbols number of uplink symbols
@returns 0 if tdd dedicated configuration has been properly set or -1 on error with message */
int set_tdd_config_nr(nfapi_nr_config_request_scf_t *cfg, int mu,
int nrofDownlinkSlots, int nrofDownlinkSymbols,
int nrofUplinkSlots, int nrofUplinkSymbols);
/** @brief This function processes TDD dedicated configuration for NR
* by processing the tdd_slot_bitmap and period_cfg, and
* allocates memory and fills max_num_of_symbol_per_slot_list
* in the nfapi config request (cfg)
* @param cfg NR config request structure pointer
* @param fs frame structure pointer
* @returns nb_periods_per_frame if TDD has been properly configurated
* -1 tdd configuration can not be done
*/
void set_tdd_config_nr(nfapi_nr_config_request_scf_t *cfg, frame_structure_t *fs);
/** \brief This function adds a slot configuration to current dedicated configuration for nr
* @param frame_parms NR DL Frame parameters
......@@ -92,5 +90,7 @@ void free_tdd_configuration_dedicated_nr(NR_DL_FRAME_PARMS *frame_parms);
int get_next_downlink_slot(PHY_VARS_gNB *gNB, nfapi_nr_config_request_scf_t *cfg, int nr_frame, int nr_slot);
void do_tdd_config_sim(PHY_VARS_gNB *gNB, int mu);
#endif /* PHY_FRAME_CONFIG_NR_H */
......@@ -388,8 +388,9 @@ int main(int argc, char **argv)
frame_parms->Ncp = extended_prefix_flag ? EXTENDED : NORMAL;
crcTableInit();
nr_phy_config_request_sim(gNB, N_RB_DL, N_RB_DL, mu, Nid_cell,SSB_positions);
gNB->gNB_config.tdd_table.tdd_period.value = 6;
set_tdd_config_nr(&gNB->gNB_config, mu, 7, 6, 2, 4);
// TDD configuration
gNB->gNB_config.tdd_table.tdd_period.value = 6;
do_tdd_config_sim(gNB, mu);
phy_init_nr_gNB(gNB);
//init_eNB_afterRU();
frame_length_complex_samples = frame_parms->samples_per_subframe;
......
......@@ -189,7 +189,7 @@ void nr_dlsim_preprocessor(module_id_t module_id,
/* the following might override the table that is mandated by RRC
* configuration */
current_BWP->mcsTableIdx = g_mcsTableIdx;
sched_pdsch->time_domain_allocation = get_dl_tda(RC.nrmac[module_id], scc, slot);
sched_pdsch->time_domain_allocation = get_dl_tda(RC.nrmac[module_id], slot);
AssertFatal(sched_pdsch->time_domain_allocation >= 0,"Unable to find PDSCH time domain allocation in list\n");
sched_pdsch->tda_info = get_dl_tda_info(current_BWP,
......
......@@ -448,13 +448,10 @@ int main(int argc, char **argv)
frame_parms->freq_range = mu<2 ? FR1 : FR2;
nr_phy_config_request_sim(gNB, N_RB_DL, N_RB_DL, mu, Nid_cell, SSB_positions);
// TDD configuration
gNB->gNB_config.tdd_table.tdd_period.value = 6;
if (mu == 0)
set_tdd_config_nr(&gNB->gNB_config, mu, 3, 6, 1, 4);
else if (mu == 1)
set_tdd_config_nr(&gNB->gNB_config, mu, 7, 6, 2, 4);
else if (mu == 3)
set_tdd_config_nr(&gNB->gNB_config, mu, 27, 6, 12, 4);
do_tdd_config_sim(gNB, mu);
phy_init_nr_gNB(gNB);
frame_parms->ssb_start_subcarrier = 12 * gNB->gNB_config.ssb_table.ssb_offset_point_a.value + ssb_subcarrier_offset;
initFloatingCoresTpool(ssb_scan_threads, &nrUE_params.Tpool, false, "UE-tpool");
......
......@@ -568,7 +568,10 @@ int main(int argc, char **argv){
memcpy((void*)&ru->config,(void*)&RC.gNB[0]->gNB_config,sizeof(ru->config));
RC.nb_nr_L1_inst=1;
set_tdd_config_nr(&gNB->gNB_config, mu, 7, 6, 2, 4);
// TDD configuration
gNB->gNB_config.tdd_table.tdd_period.value = 6;
do_tdd_config_sim(gNB, mu);
phy_init_nr_gNB(gNB);
nr_phy_init_RU(ru);
......
......@@ -433,8 +433,10 @@ int main(int argc, char **argv)
cfg->carrier_config.num_tx_ant.value = n_tx;
cfg->carrier_config.num_rx_ant.value = n_rx;
nr_phy_config_request_sim(gNB,N_RB_DL,N_RB_DL,mu,Nid_cell,SSB_positions);
// TDD configuration
gNB->gNB_config.tdd_table.tdd_period.value = 6;
set_tdd_config_nr(&gNB->gNB_config, mu, 7, 6, 2, 4);
do_tdd_config_sim(gNB, mu);
phy_init_nr_gNB(gNB);
/* RU handles rxdataF, and gNB just has a pointer. Here, we don't have an RU,
* so we need to allocate that memory as well. */
......
......@@ -406,8 +406,10 @@ int main(int argc, char **argv)
gNB->frame_parms.nb_antennas_rx = n_rx;
nr_phy_config_request_sim(gNB, N_RB_UL, N_RB_UL, mu, Nid_cell, SSB_positions);
// TDD configuration
gNB->gNB_config.tdd_table.tdd_period.value = 6;
set_tdd_config_nr(&gNB->gNB_config, mu, 7, 6, 2, 4);
do_tdd_config_sim(gNB, mu);
phy_init_nr_gNB(gNB);
//configure UE
......
......@@ -60,11 +60,11 @@ bool read_mac_sm(void* data)
rd->dl_aggr_tbs = UE->mac_stats.dl.total_bytes;
rd->ul_aggr_tbs = UE->mac_stats.ul.total_bytes;
if (is_xlsch_in_slot(RC.nrmac[mod_id]->dlsch_slot_bitmap[rd->slot / 64], rd->slot)) {
if (is_dl_slot(rd->slot, &RC.nrmac[mod_id]->frame_structure)) {
rd->dl_curr_tbs = UE->mac_stats.dl.current_bytes;
rd->dl_sched_rb = UE->mac_stats.dl.current_rbs;
}
if (is_xlsch_in_slot(RC.nrmac[mod_id]->ulsch_slot_bitmap[rd->slot / 64], rd->slot)) {
if (is_ul_slot(rd->slot, &RC.nrmac[mod_id]->frame_structure)) {
rd->ul_curr_tbs = UE->mac_stats.ul.current_bytes;
rd->ul_sched_rb = sched_ctrl->sched_pusch.rbSize;
}
......
......@@ -116,6 +116,7 @@
#define GNB_CONFIG_STRING_NROFDOWNLINKSYMBOLS "nrofDownlinkSymbols"
#define GNB_CONFIG_STRING_NROFUPLINKSLOTS "nrofUplinkSlots"
#define GNB_CONFIG_STRING_NROFUPLINKSYMBOLS "nrofUplinkSymbols"
#define GNB_CONFIG_STRING_PATTERN2 "pattern2"
#define GNB_CONFIG_STRING_DLULTRANSMISSIONPERIODICITY2 "dl_UL_TransmissionPeriodicity2"
#define GNB_CONFIG_STRING_NROFDOWNLINKSLOTS2 "nrofDownlinkSlots2"
#define GNB_CONFIG_STRING_NROFDOWNLINKSYMBOLS2 "nrofDownlinkSymbols2"
......@@ -247,11 +248,6 @@
{GNB_CONFIG_STRING_NROFDOWNLINKSYMBOLS,NULL,0,.i64ptr=&scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSymbols,.defint64val=6,TYPE_INT64,0},\
{GNB_CONFIG_STRING_NROFUPLINKSLOTS,NULL,0,.i64ptr=&scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots,.defint64val=2,TYPE_INT64,0},\
{GNB_CONFIG_STRING_NROFUPLINKSYMBOLS,NULL,0,.i64ptr=&scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols,.defint64val=4,TYPE_INT64,0},\
{GNB_CONFIG_STRING_DLULTRANSMISSIONPERIODICITY2,NULL,0,.i64ptr=&scc->tdd_UL_DL_ConfigurationCommon->pattern2->dl_UL_TransmissionPeriodicity,.defintval=-1,TYPE_INT64,0},\
{GNB_CONFIG_STRING_NROFDOWNLINKSLOTS2,NULL,0,.i64ptr=&scc->tdd_UL_DL_ConfigurationCommon->pattern2->nrofDownlinkSlots,.defint64val=-1,TYPE_INT64,0},\
{GNB_CONFIG_STRING_NROFDOWNLINKSYMBOLS2,NULL,0,.i64ptr=&scc->tdd_UL_DL_ConfigurationCommon->pattern2->nrofDownlinkSymbols,.defint64val=-1,TYPE_INT64,0},\
{GNB_CONFIG_STRING_NROFUPLINKSLOTS2,NULL,0,.i64ptr=&scc->tdd_UL_DL_ConfigurationCommon->pattern2->nrofUplinkSlots,.defint64val=-1,TYPE_INT64,0},\
{GNB_CONFIG_STRING_NROFUPLINKSYMBOLS2,NULL,0,.i64ptr=&scc->tdd_UL_DL_ConfigurationCommon->pattern2->nrofUplinkSymbols,.defint64val=-1,TYPE_INT64,0},\
{GNB_CONFIG_STRING_SSPBCHBLOCKPOWER,NULL,0,.i64ptr=&scc->ss_PBCH_BlockPower,.defint64val=20,TYPE_INT64,0}, \
{GNB_CONFIG_STRING_CELLSPECIFICKOFFSET,NULL,0,.i64ptr=scc->ext2->ntn_Config_r17->cellSpecificKoffset_r17,.defint64val=0,TYPE_INT64,0}, \
{GNB_CONFIG_STRING_EPHEMERIS_POSITION_X,NULL,0,.i64ptr=&scc->ext2->ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17->positionX_r17,.defint64val=LONG_MAX,TYPE_INT64,0}, \
......@@ -263,6 +259,15 @@
{GNB_CONFIG_STRING_TA_COMMON,NULL,0,.i64ptr=&scc->ext2->ntn_Config_r17->ta_Info_r17->ta_Common_r17,.defint64val=-1,TYPE_INT64,0}, \
{GNB_CONFIG_STRING_MSG1SUBCARRIERSPACING,NULL,0,.i64ptr=scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing,.defintval=-1,TYPE_INT64,0}}
#define SCC_PATTERN2_STRING_CONFIG "pattern2"
#define SCC_PATTERN2_PARAMS_DESC(pattern2) { \
{GNB_CONFIG_STRING_DLULTRANSMISSIONPERIODICITY2, NULL,0,.i64ptr=&pattern2.dl_UL_TransmissionPeriodicity,.defint64val=-1,TYPE_INT64,0},\
{GNB_CONFIG_STRING_NROFDOWNLINKSLOTS2, NULL,0,.i64ptr=&pattern2.nrofDownlinkSlots,.defint64val=-1,TYPE_INT64,0},\
{GNB_CONFIG_STRING_NROFDOWNLINKSYMBOLS2, NULL,0,.i64ptr=&pattern2.nrofDownlinkSymbols,.defint64val=-1,TYPE_INT64,0},\
{GNB_CONFIG_STRING_NROFUPLINKSLOTS2,NULL, 0,.i64ptr=&pattern2.nrofUplinkSlots,.defint64val=-1,TYPE_INT64,0},\
{GNB_CONFIG_STRING_NROFUPLINKSYMBOLS2,NULL, 0,.i64ptr=&pattern2.nrofUplinkSymbols,.defint64val=-1,TYPE_INT64,0}}
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* Serving Cell Config Dedicated configuration parameters */
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
......
......@@ -113,7 +113,10 @@ void prepare_scc(NR_ServingCellConfigCommon_t *scc)
scc->ssb_periodicityServingCell = calloc_or_fail(1, sizeof(*scc->ssb_periodicityServingCell));
scc->ssbSubcarrierSpacing = calloc_or_fail(1, sizeof(*scc->ssbSubcarrierSpacing));
scc->tdd_UL_DL_ConfigurationCommon = calloc_or_fail(1, sizeof(*scc->tdd_UL_DL_ConfigurationCommon));
scc->tdd_UL_DL_ConfigurationCommon->pattern2 = calloc_or_fail(1, sizeof(*scc->tdd_UL_DL_ConfigurationCommon->pattern2));
struct NR_TDD_UL_DL_ConfigCommon *tdd = scc->tdd_UL_DL_ConfigurationCommon;
tdd->pattern1.ext1 = calloc_or_fail(1, sizeof(*tdd->pattern1.ext1));
tdd->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530 =
calloc_or_fail(1, sizeof(*tdd->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530));
scc->downlinkConfigCommon = calloc_or_fail(1, sizeof(*scc->downlinkConfigCommon));
scc->downlinkConfigCommon->frequencyInfoDL = calloc_or_fail(1, sizeof(*scc->downlinkConfigCommon->frequencyInfoDL));
scc->downlinkConfigCommon->initialDownlinkBWP = calloc_or_fail(1, sizeof(*scc->downlinkConfigCommon->initialDownlinkBWP));
......@@ -357,15 +360,52 @@ void fill_scc_sim(NR_ServingCellConfigCommon_t *scc, uint64_t *ssb_bitmap, int N
p1->nrofUplinkSymbols = 4;
struct NR_TDD_UL_DL_Pattern *p2 = tdd_UL_DL_ConfigurationCommon->pattern2;
p2->dl_UL_TransmissionPeriodicity = 321;
p2->nrofDownlinkSlots = -1;
p2->nrofDownlinkSymbols = -1;
p2->nrofUplinkSlots = -1;
p2->nrofUplinkSymbols = -1;
if (p2) {
p2->dl_UL_TransmissionPeriodicity = 321;
p2->nrofDownlinkSlots = -1;
p2->nrofDownlinkSymbols = -1;
p2->nrofUplinkSlots = -1;
p2->nrofUplinkSymbols = -1;
}
scc->ss_PBCH_BlockPower = 20;
}
static void fix_tdd_pattern(NR_ServingCellConfigCommon_t *scc)
{
NR_TDD_UL_DL_Pattern_t *pattern1 = &scc->tdd_UL_DL_ConfigurationCommon->pattern1;
int pattern_ext = pattern1->dl_UL_TransmissionPeriodicity - 8;
// Check if the pattern1 extension is configured and set the value accordingly
if (pattern_ext >= 0) {
pattern1->ext1 = calloc_or_fail(1, sizeof(struct NR_TDD_UL_DL_Pattern__ext1));
pattern1->ext1->dl_UL_TransmissionPeriodicity_v1530 =
calloc_or_fail(1, sizeof(*pattern1->ext1->dl_UL_TransmissionPeriodicity_v1530));
*pattern1->ext1->dl_UL_TransmissionPeriodicity_v1530 = pattern_ext;
pattern1->dl_UL_TransmissionPeriodicity = 5;
} else {
pattern1->ext1 = NULL;
}
struct NR_TDD_UL_DL_Pattern *pattern2 = scc->tdd_UL_DL_ConfigurationCommon->pattern2;
if (pattern2 != NULL) {
/* The pattern2 is not configured free the memory these shall not be encoded with default values in SIB1 */
if (pattern2->dl_UL_TransmissionPeriodicity == -1) {
free(pattern2);
pattern2 = NULL;
} else {
// Check if the pattern2 extension is configured and set the value accordingly
pattern_ext = pattern2->dl_UL_TransmissionPeriodicity - 8;
if (pattern_ext >= 0) {
pattern2->ext1 = calloc_or_fail(1, sizeof(*pattern2->ext1));
pattern2->ext1->dl_UL_TransmissionPeriodicity_v1530 =
CALLOC(1, sizeof(*pattern2->ext1->dl_UL_TransmissionPeriodicity_v1530));
*pattern2->ext1->dl_UL_TransmissionPeriodicity_v1530 = pattern_ext;
pattern2->dl_UL_TransmissionPeriodicity = 5;
} else {
pattern2->ext1 = NULL;
}
}
}
}
void fix_scc(NR_ServingCellConfigCommon_t *scc, uint64_t ssbmap)
{
......@@ -436,11 +476,7 @@ void fix_scc(NR_ServingCellConfigCommon_t *scc, uint64_t ssbmap)
ASN_STRUCT_FREE(asn_DEF_NR_TDD_UL_DL_ConfigCommon, scc->tdd_UL_DL_ConfigurationCommon);
scc->tdd_UL_DL_ConfigurationCommon = NULL;
} else { // TDD
if (scc->tdd_UL_DL_ConfigurationCommon->pattern2->dl_UL_TransmissionPeriodicity > 320 ) {
free(scc->tdd_UL_DL_ConfigurationCommon->pattern2);
scc->tdd_UL_DL_ConfigurationCommon->pattern2 = NULL;
}
fix_tdd_pattern(scc);
}
if ((int)*scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing == -1) {
......@@ -982,6 +1018,16 @@ void RCconfig_NR_L1(void)
}
}
/**
* @brief Returns true when pattern2 is filled in
*/
bool is_pattern2_config(paramdef_t *param)
{
if (param == NULL || param->i64ptr == NULL || *(param->i64ptr) == -1)
return false;
return true;
}
static NR_ServingCellConfigCommon_t *get_scc_config(configmodule_interface_t *cfg, int minRXTXTIME)
{
NR_ServingCellConfigCommon_t *scc = calloc_or_fail(1, sizeof(*scc));
......@@ -1002,6 +1048,33 @@ static NR_ServingCellConfigCommon_t *get_scc_config(configmodule_interface_t *cf
sprintf(aprefix, "%s.[%i].%s.[%i]", GNB_CONFIG_STRING_GNB_LIST,0,GNB_CONFIG_STRING_SERVINGCELLCONFIGCOMMON, 0);
config_get(cfg, SCCsParams, sizeofArray(SCCsParams), aprefix);
config_get(cfg, MsgASCCsParams, sizeofArray(MsgASCCsParams), aprefix);
// NR_TDD-UL-DL-ConfigCommon pattern2 (optional IE)
// fetch params
struct NR_TDD_UL_DL_Pattern p2;
paramdef_t pattern2Params[] = SCC_PATTERN2_PARAMS_DESC(p2);
char aprefix[MAX_OPTNAME_SIZE * 2 + 8];
sprintf(aprefix, "%s.[%i].%s.[%i].%s", GNB_CONFIG_STRING_GNB_LIST, 0, GNB_CONFIG_STRING_SERVINGCELLCONFIGCOMMON, 0, SCC_PATTERN2_STRING_CONFIG);
config_get(config_get_if(), pattern2Params, sizeofArray(pattern2Params), aprefix);
// check validity
bool is_pattern2 = false;
for (int i = 0; i < sizeofArray(pattern2Params); i++) {
is_pattern2 |= is_pattern2_config(pattern2Params);
}
if (is_pattern2) {
LOG_I(GNB_APP, "tdd->pattern2 present\n");
// allocate memory
struct NR_TDD_UL_DL_ConfigCommon *tdd = scc->tdd_UL_DL_ConfigurationCommon;
tdd->pattern2 = calloc_or_fail(1, sizeof(*tdd->pattern2));
tdd->pattern2->ext1 = calloc_or_fail(1, sizeof(struct NR_TDD_UL_DL_Pattern__ext1));
tdd->pattern2->ext1->dl_UL_TransmissionPeriodicity_v1530 = calloc_or_fail(1, sizeof(*tdd->pattern2->ext1->dl_UL_TransmissionPeriodicity_v1530));
// fill in scc
*scc->tdd_UL_DL_ConfigurationCommon->pattern2 = p2;
AssertFatal(p2.nrofUplinkSlots ^ scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots,
"UL slots in pattern1 (%ld) and pattern2 (%ld) are mutually exclusive (e.g. DDDFUU DDDD, DDDD DDDFUU)\n",
scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots,
p2.nrofUplinkSlots);
}
struct NR_FrequencyInfoDL *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL;
LOG_I(RRC,
"Read in ServingCellConfigCommon (PhysCellId %d, ABSFREQSSB %d, DLBand %d, ABSFREQPOINTA %d, DLBW "
......
This diff is collapsed.
......@@ -122,8 +122,49 @@ void clear_beam_information(NR_beam_info_t *beam_info, int frame, int slot, int
}
}
bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot) {
return (bitmap >> (slot % 64)) & 0x01;
/**
* @brief Returns true for:
* (1) FDD
* (2) Mixed slot with UL symbols
* (3) Full UL slot
*/
bool is_ul_slot(const slot_t slot, const frame_structure_t *fs)
{
if (!fs->is_tdd)
return true;
const tdd_period_config_t *pc = &fs->period_cfg;
slot_t s = get_slot_idx_in_period(slot, fs);
return ((is_mixed_slot(s, fs) && pc->tdd_slot_bitmap[s].num_ul_symbols)
|| (pc->tdd_slot_bitmap[s].slot_type == TDD_NR_UPLINK_SLOT));
}
/**
* @brief Returns true for:
* (1) FDD
* (2) Mixed slot with DL symbols
* (3) Full DL slot
*/
bool is_dl_slot(const slot_t slot, const frame_structure_t *fs)
{
if (!fs->is_tdd)
return true;
const tdd_period_config_t *pc = &fs->period_cfg;
slot_t s = get_slot_idx_in_period(slot, fs);
return ((is_mixed_slot(s, fs) && pc->tdd_slot_bitmap[s].num_dl_symbols)
|| (pc->tdd_slot_bitmap[s].slot_type == TDD_NR_DOWNLINK_SLOT));
}
/**
* @brief Returns true for:
* (1) Mixed slot with DL and/or UL symbols
*/
bool is_mixed_slot(const slot_t slot, const frame_structure_t *fs)
{
if (!fs->is_tdd)
return false;
slot_t s = get_slot_idx_in_period(slot, fs);
const tdd_period_config_t *pc = &fs->period_cfg;
return pc->tdd_slot_bitmap[s].slot_type == TDD_NR_MIXED_SLOT;
}
/* the structure nfapi_nr_ul_tti_request_t is very big, let's copy only what is necessary */
......
......@@ -276,7 +276,7 @@ static void schedule_nr_MsgA_pusch(NR_UplinkConfigCommon_t *uplinkConfigCommon,
UL_tti_req->SFN = msgA_pusch_frame;
UL_tti_req->Slot = msgA_pusch_slot;
AssertFatal(is_xlsch_in_slot(nr_mac->ulsch_slot_bitmap[msgA_pusch_slot / 64], msgA_pusch_slot),
AssertFatal(is_ul_slot(msgA_pusch_slot, &nr_mac->frame_structure),
"Slot %d is not an Uplink slot, invalid msgA_PUSCH_TimeDomainOffset_r16 %ld\n",
msgA_pusch_slot,
msgA_PUSCH_Resource->msgA_PUSCH_TimeDomainOffset_r16);
......@@ -374,7 +374,7 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP
nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[module_idP]->UL_tti_req_ahead[0][index];
nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[module_idP]->config[0];
if (is_nr_UL_slot(scc->tdd_UL_DL_ConfigurationCommon, slotP, cc->frame_type)) {
if (is_ul_slot(slotP, &RC.nrmac[module_idP]->frame_structure)) {
const NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &rach_ConfigCommon->rach_ConfigGeneric;
uint8_t config_index = rach_ConfigGeneric->prach_ConfigurationIndex;
uint8_t N_dur, N_t_slot, start_symbol = 0, N_RA_slot;
......@@ -785,7 +785,7 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP,
const int sched_frame = (frame + (slot + K2) / nr_slots_per_frame[mu]) % MAX_FRAME_NUMBER;
const int sched_slot = (slot + K2) % nr_slots_per_frame[mu];
if (is_xlsch_in_slot(nr_mac->ulsch_slot_bitmap[sched_slot / 64], sched_slot)) {
if (is_ul_slot(sched_slot, &nr_mac->frame_structure)) {
const int n_slots_frame = nr_slots_per_frame[mu];
NR_beam_alloc_t beam_ul = beam_allocation_procedure(&nr_mac->beam_info, sched_frame, sched_slot, ra->beam_id, n_slots_frame);
if (beam_ul.idx < 0)
......@@ -950,47 +950,44 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP,
ra->ra_state = nrRA_WAIT_Msg3;
ra->Msg3_frame = sched_frame;
ra->Msg3_slot = sched_slot;
}
}
static bool get_feasible_msg3_tda(frame_type_t frame_type,
const NR_ServingCellConfigCommon_t *scc,
static bool get_feasible_msg3_tda(const NR_ServingCellConfigCommon_t *scc,
int mu_delta,
uint64_t ulsch_slot_bitmap[3],
const NR_PUSCH_TimeDomainResourceAllocationList_t *tda_list,
int slots_per_frame,
int frame,
int slot,
NR_RA_t *ra,
NR_beam_info_t *beam_info,
const NR_TDD_UL_DL_Pattern_t *tdd)
const frame_structure_t *fs)
{
DevAssert(tda_list != NULL);
const int NTN_gNB_Koffset = get_NTN_Koffset(scc);
int tdd_period_slot = tdd ? slots_per_frame / get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity) : slots_per_frame;
int slots_per_frame = fs->numb_slots_frame;
for (int i = 0; i < tda_list->list.count; i++) {
// check if it is UL
long k2 = *tda_list->list.array[i]->k2 + NTN_gNB_Koffset;
int abs_slot = slot + k2 + mu_delta;
int temp_frame = (frame + (abs_slot / slots_per_frame)) & 1023;
int temp_slot = abs_slot % slots_per_frame; // msg3 slot according to 8.3 in 38.213
if ((frame_type == TDD) && !is_xlsch_in_slot(ulsch_slot_bitmap[temp_slot / 64], temp_slot))
if (fs->is_tdd && !is_ul_slot(temp_slot, fs))
continue;
const tdd_bitmap_t *tdd_slot_bitmap = fs->period_cfg.tdd_slot_bitmap;
int s = get_slot_idx_in_period(temp_slot, fs);
// check if enough symbols in case of mixed slot
bool is_mixed = false;
if (frame_type == TDD) {
bool has_mixed = tdd->nrofUplinkSymbols != 0 || tdd->nrofDownlinkSymbols != 0;
is_mixed = has_mixed && ((temp_slot % tdd_period_slot) == tdd->nrofDownlinkSlots);
}
bool is_mixed = is_mixed_slot(s, fs);
// if the mixed slot has not enough symbols, skip
if (is_mixed && tdd->nrofUplinkSymbols < 3)
if (is_mixed && tdd_slot_bitmap[s].num_ul_symbols < 3)
continue;
uint16_t slot_mask = is_mixed ? SL_to_bitmap(14 - tdd->nrofUplinkSymbols, tdd->nrofUplinkSymbols) : 0x3fff;
uint16_t slot_mask =
is_mixed ? SL_to_bitmap(NR_NUMBER_OF_SYMBOLS_PER_SLOT - tdd_slot_bitmap[s].num_ul_symbols,
tdd_slot_bitmap[s].num_ul_symbols)
: 0x3fff;
long startSymbolAndLength = tda_list->list.array[i]->startSymbolAndLength;
int start, nr;
SLIV2SL(startSymbolAndLength, &start, &nr);
......@@ -1385,7 +1382,7 @@ static void nr_generate_Msg2(module_id_t module_idP,
gNB_MAC_INST *nr_mac = RC.nrmac[module_idP];
// no DL -> cannot send Msg2
if (!is_xlsch_in_slot(nr_mac->dlsch_slot_bitmap[slotP / 64], slotP)) {
if (!is_dl_slot(slotP, &nr_mac->frame_structure)) {
return;
}
......@@ -1413,18 +1410,14 @@ static void nr_generate_Msg2(module_id_t module_idP,
return;
const NR_UE_UL_BWP_t *ul_bwp = &ra->UL_BWP;
const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
bool ret = get_feasible_msg3_tda(cc->frame_type,
scc,
bool ret = get_feasible_msg3_tda(scc,
DELTA[ul_bwp->scs],
nr_mac->ulsch_slot_bitmap,
ul_bwp->tdaList_Common,
nr_slots_per_frame[ul_bwp->scs],
frameP,
slotP,
ra,
&nr_mac->beam_info,
tdd);
&nr_mac->frame_structure);
if (!ret || ra->Msg3_tda_id > 15) {
LOG_D(NR_MAC, "UE RNTI %04x %d.%d: infeasible Msg3 TDA\n", ra->rnti, frameP, slotP);
reset_beam_status(&nr_mac->beam_info, frameP, slotP, ra->beam_id, n_slots_frame, beam.new_beam);
......@@ -1453,7 +1446,7 @@ static void nr_generate_Msg2(module_id_t module_idP,
AssertFatal(coreset, "Coreset cannot be null for RA-Msg2\n");
const int coresetid = coreset->controlResourceSetId;
// Calculate number of symbols
int time_domain_assignment = get_dl_tda(nr_mac, scc, slotP);
int time_domain_assignment = get_dl_tda(nr_mac, slotP);
int mux_pattern = type0_PDCCH_CSS_config ? type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern : 1;
NR_tda_info_t tda_info = get_dl_tda_info(dl_bwp,
ss->searchSpaceType->present,
......@@ -1949,8 +1942,8 @@ static void nr_generate_Msg4_MsgB(module_id_t module_idP,
NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id];
NR_UE_DL_BWP_t *dl_bwp = &ra->DL_BWP;
// if it is a DL slot, if the RA is in MSG4 state
if (is_xlsch_in_slot(nr_mac->dlsch_slot_bitmap[slotP / 64], slotP)) {
// if it is a DL slot, if the RA is in MSG4 state
if (is_dl_slot(slotP, &nr_mac->frame_structure)) {
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
NR_SearchSpace_t *ss = ra->ra_ss;
const char *ra_type_str = ra->ra_type == RA_2_STEP ? "MsgB" : "Msg4";
......@@ -2029,7 +2022,7 @@ static void nr_generate_Msg4_MsgB(module_id_t module_idP,
return;
}
uint8_t time_domain_assignment = get_dl_tda(nr_mac, scc, slotP);
uint8_t time_domain_assignment = get_dl_tda(nr_mac, slotP);
int mux_pattern = type0_PDCCH_CSS_config ? type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern : 1;
NR_tda_info_t msg4_tda = get_dl_tda_info(dl_bwp,
ss->searchSpaceType->present,
......
......@@ -52,20 +52,22 @@
#define WORD 32
//#define SIZE_OF_POINTER sizeof (void *)
int get_dl_tda(const gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *scc, int slot)
int get_dl_tda(const gNB_MAC_INST *nrmac, int slot)
{
/* we assume that this function is mutex-protected from outside */
const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
AssertFatal(tdd || nrmac->common_channels->frame_type == FDD, "Dynamic TDD not handled yet\n");
const frame_structure_t *fs = &nrmac->frame_structure;
// Use special TDA in case of CSI-RS
if(nrmac->UE_info.sched_csirs > 0)
if (nrmac->UE_info.sched_csirs > 0)
return 1;
if (tdd && tdd->nrofDownlinkSymbols > 1) { // if there is a mixed slot where we can transmit DL
const int nr_slots_period = tdd->nrofDownlinkSlots + tdd->nrofUplinkSlots + 1;
if ((slot % nr_slots_period) == tdd->nrofDownlinkSlots)
if (fs->is_tdd) {
int s = get_slot_idx_in_period(slot, fs);
// if there is a mixed slot where we can transmit DL
const tdd_bitmap_t *tdd_slot_bitmap = fs->period_cfg.tdd_slot_bitmap;
if (tdd_slot_bitmap[s].num_dl_symbols > 1 && is_mixed_slot(s, fs)) {
return 2;
}
}
return 0; // if FDD or not mixed slot in TDD, for now use default TDA
}
......@@ -447,7 +449,7 @@ static bool allocate_dl_retransmission(module_id_t module_id,
int pm_index = (curInfo->nrOfLayers < retInfo->nrOfLayers) ? curInfo->pm_index : retInfo->pm_index;
const int coresetid = sched_ctrl->coreset->controlResourceSetId;
const int tda = get_dl_tda(nr_mac, scc, slot);
const int tda = get_dl_tda(nr_mac, slot);
AssertFatal(tda >= 0,"Unable to find PDSCH time domain allocation in list\n");
/* Check first whether the old TDA can be reused
......@@ -761,7 +763,7 @@ static void pf_dl(module_id_t module_id,
sched_pdsch->dl_harq_pid = sched_ctrl->available_dl_harq.head;
/* MCS has been set above */
sched_pdsch->time_domain_allocation = get_dl_tda(mac, scc, slot);
sched_pdsch->time_domain_allocation = get_dl_tda(mac, slot);
AssertFatal(sched_pdsch->time_domain_allocation>=0,"Unable to find PDSCH time domain allocation in list\n");
const int coresetid = sched_ctrl->coreset->controlResourceSetId;
......@@ -955,7 +957,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
AssertFatal(pthread_mutex_trylock(&gNB_mac->sched_lock) == EBUSY,
"this function should be called with the scheduler mutex locked\n");
if (!is_xlsch_in_slot(gNB_mac->dlsch_slot_bitmap[slot / 64], slot))
if (!is_dl_slot(slot, &gNB_mac->frame_structure))
return;
/* PREPROCESSOR */
......
......@@ -40,6 +40,14 @@
// #define UL_HARQ_PRINT
// #define ENABLE_MAC_PAYLOAD_DEBUG 1
/* This function checks whether the given Dl/UL slot is set
in the input bitmap, which is a mask indicating in which
slot to transmit (among those available in the TDD configuration) */
static bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot)
{
return (bitmap >> (slot % 64)) & 0x01;
}
uint32_t target_dl_mcs = 9;
uint32_t target_dl_Nl = 1;
uint32_t target_dl_bw = 50;
......@@ -64,7 +72,7 @@ void nr_preprocessor_phytest(module_id_t module_id,
return;
}
const int tda = get_dl_tda(RC.nrmac[module_id], scc, slot);
const int tda = get_dl_tda(RC.nrmac[module_id], slot);
NR_tda_info_t tda_info = get_dl_tda_info(dl_bwp,
sched_ctrl->search_space->searchSpaceType->present,
tda,
......@@ -242,7 +250,7 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_
sched_ctrl->coreset->controlResourceSetId,
sched_ctrl->search_space->searchSpaceType->present,
TYPE_C_RNTI_);
const int temp_tda = get_ul_tda(nr_mac, scc, frame, slot);
const int temp_tda = get_ul_tda(nr_mac, frame, slot);
if (temp_tda < 0)
return false;
AssertFatal(temp_tda < tdaList->list.count,
......@@ -252,7 +260,7 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_
int K2 = get_K2(tdaList, temp_tda, mu, scc);
const int sched_frame = (frame + (slot + K2) / nr_slots_per_frame[mu]) % MAX_FRAME_NUMBER;
const int sched_slot = (slot + K2) % nr_slots_per_frame[mu];
const int tda = get_ul_tda(nr_mac, scc, sched_frame, sched_slot);
const int tda = get_ul_tda(nr_mac, sched_frame, sched_slot);
if (tda < 0)
return false;
AssertFatal(tda < tdaList->list.count,
......
......@@ -2160,6 +2160,31 @@ int get_ulbw_tbslbrm(int scc_bwpsize, const NR_ServingCellConfig_t *servingCellC
return bw;
}
static void set_sched_pucch_list(NR_UE_sched_ctrl_t *sched_ctrl,
const NR_UE_UL_BWP_t *ul_bwp,
const NR_ServingCellConfigCommon_t *scc,
const frame_structure_t *fs)
{
const int NTN_gNB_Koffset = get_NTN_Koffset(scc);
const int n_ul_slots_period = get_ul_slots_per_period(fs);
// PUCCH list size is given by the number of UL slots in the PUCCH period
// the length PUCCH period is determined by max_fb_time since we may need to prepare PUCCH for ACK/NACK max_fb_time slots ahead
const int list_size = n_ul_slots_period << (int)ceil(log2((ul_bwp->max_fb_time + NTN_gNB_Koffset) / fs->numb_slots_period + 1));
if (!sched_ctrl->sched_pucch) {
sched_ctrl->sched_pucch = calloc_or_fail(list_size, sizeof(*sched_ctrl->sched_pucch));
sched_ctrl->sched_pucch_size = list_size;
} else if (list_size > sched_ctrl->sched_pucch_size) {
sched_ctrl->sched_pucch = realloc(sched_ctrl->sched_pucch, list_size * sizeof(*sched_ctrl->sched_pucch));
for (int i = sched_ctrl->sched_pucch_size; i < list_size; i++) {
NR_sched_pucch_t *curr_pucch = &sched_ctrl->sched_pucch[i];
memset(curr_pucch, 0, sizeof(*curr_pucch));
}
sched_ctrl->sched_pucch_size = list_size;
}
}
// main function to configure parameters of current BWP
void configure_UE_BWP(gNB_MAC_INST *nr_mac,
NR_ServingCellConfigCommon_t *scc,
......@@ -2405,7 +2430,7 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac,
NR_UL_DCI_FORMAT_0_0;
set_max_fb_time(UL_BWP, DL_BWP);
set_sched_pucch_list(sched_ctrl, UL_BWP, scc);
set_sched_pucch_list(sched_ctrl, UL_BWP, scc, &nr_mac->frame_structure);
}
if(ra) {
......@@ -2537,32 +2562,6 @@ NR_UE_info_t *add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConf
return (UE);
}
void set_sched_pucch_list(NR_UE_sched_ctrl_t *sched_ctrl,
const NR_UE_UL_BWP_t *ul_bwp,
const NR_ServingCellConfigCommon_t *scc)
{
const int NTN_gNB_Koffset = get_NTN_Koffset(scc);
const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
const int n_slots_frame = nr_slots_per_frame[ul_bwp->scs];
const int nr_slots_period = tdd ? n_slots_frame / get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity) : n_slots_frame;
const int n_ul_slots_period = tdd ? tdd->nrofUplinkSlots + (tdd->nrofUplinkSymbols > 0 ? 1 : 0) : n_slots_frame;
// PUCCH list size is given by the number of UL slots in the PUCCH period
// the length PUCCH period is determined by max_fb_time since we may need to prepare PUCCH for ACK/NACK max_fb_time slots ahead
const int list_size = n_ul_slots_period << (int)ceil(log2((ul_bwp->max_fb_time + NTN_gNB_Koffset) / nr_slots_period + 1));
if(!sched_ctrl->sched_pucch) {
sched_ctrl->sched_pucch = calloc(list_size, sizeof(*sched_ctrl->sched_pucch));
sched_ctrl->sched_pucch_size = list_size;
}
else if (list_size > sched_ctrl->sched_pucch_size) {
sched_ctrl->sched_pucch = realloc(sched_ctrl->sched_pucch, list_size * sizeof(*sched_ctrl->sched_pucch));
for(int i=sched_ctrl->sched_pucch_size; i<list_size; i++){
NR_sched_pucch_t *curr_pucch = &sched_ctrl->sched_pucch[i];
memset(curr_pucch, 0, sizeof(*curr_pucch));
}
sched_ctrl->sched_pucch_size = list_size;
}
}
void free_sched_pucch_list(NR_UE_sched_ctrl_t *sched_ctrl)
{
free(sched_ctrl->sched_pucch);
......
......@@ -133,23 +133,35 @@ static const int diff_rsrp_ssb_csi_meas_10_1_6_1_2[16] = {
-30 // 10 - 15
};
static int get_pucch_index(int frame, int slot, int n_slots_frame, const NR_TDD_UL_DL_Pattern_t *tdd, int sched_pucch_size)
static int get_pucch_index(int frame, int slot, const frame_structure_t *fs, int sched_pucch_size)
{
// PUCCH structures are indexed by slot in the PUCCH period determined by sched_pucch_size number of UL slots
// this functions return the index to the structure for slot passed to the function
const int first_ul_slot_period = tdd ? get_first_ul_slot(tdd->nrofDownlinkSlots, tdd->nrofDownlinkSymbols, tdd->nrofUplinkSymbols) : 0;
const int n_ul_slots_period = tdd ? tdd->nrofUplinkSlots + (tdd->nrofUplinkSymbols > 0 ? 1 : 0) : n_slots_frame;
const int nr_slots_period = tdd ? n_slots_frame / get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity) : n_slots_frame;
const int n_ul_slots_frame = n_slots_frame / nr_slots_period * n_ul_slots_period;
const int n_ul_slots_period = get_ul_slots_per_period(fs);
const int n_ul_slots_frame = get_ul_slots_per_frame(fs);
// (frame * n_ul_slots_frame) adds up the number of UL slots in the previous frames
const int frame_start = frame * n_ul_slots_frame;
// ((slot / nr_slots_period) * n_ul_slots_period) adds up the number of UL slots in the previous TDD periods of this frame
const int ul_period_start = (slot / nr_slots_period) * n_ul_slots_period;
const int ul_period_start = (slot / fs->numb_slots_period) * n_ul_slots_period;
// ((slot % nr_slots_period) - first_ul_slot_period) gives the progressive number of the slot in this TDD period
const int ul_period_slot = (slot % nr_slots_period) - first_ul_slot_period;
int ul_period_slot = -1;
for (int i = 0; i <= slot % fs->numb_slots_period; i++) {
if (is_ul_slot(i, fs)) {
ul_period_slot++;
}
}
LOG_D(NR_MAC,
"PUCCH frame/slot: request %4d.%2d:frame_start %d,ul_period_start %d, ul_period_slot %d pucch_index %d pucch_size %d "
"scheduling PUCCH\n",
frame,
slot,
frame_start,
ul_period_start,
ul_period_slot,
((frame_start + ul_period_start + ul_period_slot) % sched_pucch_size),
sched_pucch_size);
// the sum gives the index of current UL slot in the frame which is normalized wrt sched_pucch_size
return (frame_start + ul_period_start + ul_period_slot) % sched_pucch_size;
}
void nr_schedule_pucch(gNB_MAC_INST *nrmac, frame_t frameP, sub_frame_t slotP)
......@@ -157,17 +169,12 @@ void nr_schedule_pucch(gNB_MAC_INST *nrmac, frame_t frameP, sub_frame_t slotP)
/* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */
NR_SCHED_ENSURE_LOCKED(&nrmac->sched_lock);
if (!is_xlsch_in_slot(nrmac->ulsch_slot_bitmap[slotP / 64], slotP))
if (!is_ul_slot(slotP, &nrmac->frame_structure))
return;
UE_iterator(nrmac->UE_info.list, UE) {
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP;
const int n_slots_frame = nr_slots_per_frame[ul_bwp->scs];
const NR_ServingCellConfigCommon_t *scc = nrmac->common_channels[0].ServingCellConfigCommon;
const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
AssertFatal(tdd || nrmac->common_channels[0].frame_type == FDD, "Dynamic TDD not handled yet\n");
const int pucch_index = get_pucch_index(frameP, slotP, n_slots_frame, tdd, sched_ctrl->sched_pucch_size);
const int pucch_index = get_pucch_index(frameP, slotP, &nrmac->frame_structure, sched_ctrl->sched_pucch_size);
NR_sched_pucch_t *curr_pucch = &UE->UE_sched_ctrl.sched_pucch[pucch_index];
if (!curr_pucch->active)
continue;
......@@ -236,7 +243,7 @@ void nr_csi_meas_reporting(int Mod_idP,frame_t frame, sub_frame_t slot)
if ((sched_frame * n_slots_frame + sched_slot - offset) % period != 0)
continue;
AssertFatal(is_xlsch_in_slot(nrmac->ulsch_slot_bitmap[sched_slot / 64], sched_slot), "CSI reporting slot %d is not set for an uplink slot\n", sched_slot);
AssertFatal(is_ul_slot(sched_slot, &nrmac->frame_structure), "CSI reporting slot %d is not set for an uplink slot\n", sched_slot);
LOG_D(NR_MAC, "CSI reporting in frame %d slot %d CSI report ID %ld\n", sched_frame, sched_slot, csirep->reportConfigId);
const NR_PUCCH_ResourceSet_t *pucchresset = pucch_Config->resourceSetToAddModList->list.array[1]; // set with formats >1
......@@ -248,9 +255,7 @@ void nr_csi_meas_reporting(int Mod_idP,frame_t frame, sub_frame_t slot)
AssertFatal(res_index < n,
"CSI pucch resource %ld not found among PUCCH resources\n", pucchcsires->pucch_Resource);
const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
AssertFatal(tdd || nrmac->common_channels[0].frame_type == FDD, "Dynamic TDD not handled yet\n");
const int pucch_index = get_pucch_index(sched_frame, sched_slot, n_slots_frame, tdd, sched_ctrl->sched_pucch_size);
const int pucch_index = get_pucch_index(sched_frame, sched_slot, &nrmac->frame_structure, sched_ctrl->sched_pucch_size);
NR_sched_pucch_t *curr_pucch = &sched_ctrl->sched_pucch[pucch_index];
AssertFatal(curr_pucch->active == false, "CSI structure is scheduled in advance. It should be free!\n");
curr_pucch->r_pucch = -1;
......@@ -998,10 +1003,7 @@ int nr_acknack_scheduling(gNB_MAC_INST *mac,
const int minfbtime = mac->radio_config.minRXTXTIME + NTN_gNB_Koffset;
const NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP;
const int n_slots_frame = nr_slots_per_frame[ul_bwp->scs];
const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
AssertFatal(tdd || mac->common_channels[CC_id].frame_type == FDD, "Dynamic TDD not handled yet\n");
const int nr_slots_period = tdd ? n_slots_frame / get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity) : n_slots_frame;
const int first_ul_slot_period = tdd ? get_first_ul_slot(tdd->nrofDownlinkSlots, tdd->nrofDownlinkSymbols, tdd->nrofUplinkSymbols) : 0;
const frame_structure_t *fs = &mac->frame_structure;
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
NR_PUCCH_Config_t *pucch_Config = ul_bwp->pucch_Config;
......@@ -1022,11 +1024,14 @@ int nr_acknack_scheduling(gNB_MAC_INST *mac,
continue;
const int pucch_slot = (slot + pdsch_to_harq_feedback[f] + NTN_gNB_Koffset) % n_slots_frame;
// check if the slot is UL
if(pucch_slot%nr_slots_period < first_ul_slot_period)
continue;
if (fs->is_tdd) {
int mod_slot = pucch_slot % fs->numb_slots_period;
if (!is_ul_slot(mod_slot, fs))
continue;
}
const int pucch_frame = (frame + ((slot + pdsch_to_harq_feedback[f] + NTN_gNB_Koffset) / n_slots_frame)) % MAX_FRAME_NUMBER;
// we store PUCCH resources according to slot, TDD configuration and size of the vector containing PUCCH structures
const int pucch_index = get_pucch_index(pucch_frame, pucch_slot, n_slots_frame, tdd, sched_ctrl->sched_pucch_size);
const int pucch_index = get_pucch_index(pucch_frame, pucch_slot, &mac->frame_structure, sched_ctrl->sched_pucch_size);
NR_sched_pucch_t *curr_pucch = &sched_ctrl->sched_pucch[pucch_index];
if (curr_pucch->active &&
curr_pucch->frame == pucch_frame &&
......@@ -1125,7 +1130,7 @@ void nr_sr_reporting(gNB_MAC_INST *nrmac, frame_t SFN, sub_frame_t slot)
/* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */
NR_SCHED_ENSURE_LOCKED(&nrmac->sched_lock);
if (!is_xlsch_in_slot(nrmac->ulsch_slot_bitmap[slot / 64], slot))
if (!is_ul_slot(slot, &nrmac->frame_structure))
return;
const int CC_id = 0;
UE_iterator(nrmac->UE_info.list, UE) {
......@@ -1164,10 +1169,7 @@ void nr_sr_reporting(gNB_MAC_INST *nrmac, frame_t SFN, sub_frame_t slot)
}
AssertFatal(idx > -1, "SR resource not found among PUCCH resources");
const NR_ServingCellConfigCommon_t *scc = nrmac->common_channels[CC_id].ServingCellConfigCommon;
const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
AssertFatal(tdd || nrmac->common_channels[CC_id].frame_type == FDD, "Dynamic TDD not handled yet\n");
const int pucch_index = get_pucch_index(SFN, slot, n_slots_frame, tdd, sched_ctrl->sched_pucch_size);
const int pucch_index = get_pucch_index(SFN, slot, &nrmac->frame_structure, sched_ctrl->sched_pucch_size);
NR_sched_pucch_t *curr_pucch = &sched_ctrl->sched_pucch[pucch_index];
if (curr_pucch->active && curr_pucch->frame == SFN && curr_pucch->ul_slot == slot && curr_pucch->resource_indicator == idx)
......
......@@ -40,19 +40,21 @@
//#define SRS_IND_DEBUG
int get_ul_tda(gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *scc, int frame, int slot)
int get_ul_tda(gNB_MAC_INST *nrmac, int frame, int slot)
{
/* we assume that this function is mutex-protected from outside */
NR_SCHED_ENSURE_LOCKED(&nrmac->sched_lock);
/* there is a mixed slot only when in TDD */
const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
AssertFatal(tdd || nrmac->common_channels->frame_type == FDD, "Dynamic TDD not handled yet\n");
frame_structure_t *fs = &nrmac->frame_structure;
if (tdd && tdd->nrofUplinkSymbols > 1) { // if there is uplink symbols in mixed slot
const int nr_slots_period = tdd->nrofDownlinkSlots + tdd->nrofUplinkSlots + 1;
if ((slot % nr_slots_period) == tdd->nrofDownlinkSlots)
if (fs->is_tdd) {
// if there is uplink symbols in mixed slot
int s = get_slot_idx_in_period(slot, fs);
tdd_bitmap_t *tdd_slot_bitmap = fs->period_cfg.tdd_slot_bitmap;
if ((tdd_slot_bitmap[s].num_ul_symbols > 1) && is_mixed_slot(s, fs)) {
return 2;
}
}
// Avoid slots with the SRS
......@@ -1519,25 +1521,21 @@ long get_K2(NR_PUSCH_TimeDomainResourceAllocationList_t *tdaList,
return 3 + NTN_gNB_Koffset;
}
static bool nr_UE_is_to_be_scheduled(const NR_ServingCellConfigCommon_t *scc, int CC_id, NR_UE_info_t* UE, frame_t frame, sub_frame_t slot, uint32_t ulsch_max_frame_inactivity)
static bool nr_UE_is_to_be_scheduled(const frame_structure_t *fs,
NR_UE_info_t *UE,
frame_t frame,
sub_frame_t slot,
uint32_t ulsch_max_frame_inactivity)
{
const int n = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
const int n = fs->numb_slots_frame;
const int now = frame * n + slot;
const NR_UE_sched_ctrl_t *sched_ctrl =&UE->UE_sched_ctrl;
const NR_TDD_UL_DL_Pattern_t *tdd =
scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
int num_slots_per_period;
int last_ul_slot;
if (tdd) { // Force the default transmission in a full slot as early as possible in the UL portion of TDD period (last_ul_slot)
num_slots_per_period = n / get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity);
last_ul_slot = 1 + tdd->nrofDownlinkSlots;
} else {
num_slots_per_period = n;
last_ul_slot = sched_ctrl->last_ul_slot;
}
/**
* Force the default transmission in a full slot as early
* as possible in the UL portion of TDD period (last_ul_slot) */
int num_slots_per_period = fs->numb_slots_period;
int last_ul_slot = fs->is_tdd ? get_first_ul_slot(fs, false) : sched_ctrl->last_ul_slot;
const int last_ul_sched = sched_ctrl->last_ul_frame * n + last_ul_slot;
const int diff = (now - last_ul_sched + 1024 * n) % (1024 * n);
/* UE is to be scheduled if
......@@ -1856,7 +1854,7 @@ static void pf_ul(module_id_t module_id,
LOG_D(NR_MAC,"pf_ul: UE %04x harq_pid %d\n", UE->rnti, sched_pusch->ul_harq_pid);
if (sched_pusch->ul_harq_pid >= 0) {
/* Allocate retransmission*/
const int tda = get_ul_tda(nrmac, scc, sched_frame, sched_slot);
const int tda = get_ul_tda(nrmac, sched_frame, sched_slot);
bool r = allocate_ul_retransmission(nrmac,
frame,
slot,
......@@ -1893,7 +1891,11 @@ static void pf_ul(module_id_t module_id,
const int B = max(0, sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes);
/* preprocessor computed sched_frame/sched_slot */
const bool do_sched = nr_UE_is_to_be_scheduled(scc, 0, UE, sched_frame, sched_slot, nrmac->ulsch_max_frame_inactivity);
const bool do_sched = nr_UE_is_to_be_scheduled(&nrmac->frame_structure,
UE,
sched_frame,
sched_slot,
nrmac->ulsch_max_frame_inactivity);
LOG_D(NR_MAC,"pf_ul: do_sched UE %04x => %s\n", UE->rnti, do_sched ? "yes" : "no");
if ((B == 0 && !do_sched) || nr_timer_is_active(&sched_ctrl->transm_interrupt)) {
......@@ -1933,7 +1935,7 @@ static void pf_ul(module_id_t module_id,
}
sched_pusch->nrOfLayers = sched_ctrl->srs_feedback.ul_ri + 1;
sched_pusch->time_domain_allocation = get_ul_tda(nrmac, scc, sched_frame, sched_slot);
sched_pusch->time_domain_allocation = get_ul_tda(nrmac, sched_frame, sched_slot);
sched_pusch->tda_info = get_ul_tda_info(current_BWP,
sched_ctrl->coreset->controlResourceSetId,
sched_ctrl->search_space->searchSpaceType->present,
......@@ -2086,7 +2088,7 @@ static void pf_ul(module_id_t module_id,
sched_pusch->nrOfLayers = sched_ctrl->srs_feedback.ul_ri + 1;
sched_pusch->time_domain_allocation = get_ul_tda(nrmac, scc, sched_frame, sched_slot);
sched_pusch->time_domain_allocation = get_ul_tda(nrmac, sched_frame, sched_slot);
sched_pusch->tda_info = get_ul_tda_info(current_BWP,
sched_ctrl->coreset->controlResourceSetId,
sched_ctrl->search_space->searchSpaceType->present,
......@@ -2215,7 +2217,7 @@ static bool nr_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_fram
const int K2 = nr_mac->radio_config.minRXTXTIME + get_NTN_Koffset(scc);
const int sched_frame = (frame + (slot + K2) / slots_frame) % MAX_FRAME_NUMBER;
const int sched_slot = (slot + K2) % slots_frame;
if (!is_xlsch_in_slot(nr_mac->ulsch_slot_bitmap[sched_slot / 64], sched_slot))
if (!is_ul_slot(sched_slot, &nr_mac->frame_structure))
return false;
int num_beams = nr_mac->beam_info.beam_allocation ? nr_mac->beam_info.beams_per_period : 1;
......@@ -2274,7 +2276,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot, n
/* Uplink data ONLY can be scheduled when the current slot is downlink slot,
* because we have to schedule the DCI0 first before schedule uplink data */
if (!is_xlsch_in_slot(nr_mac->dlsch_slot_bitmap[slot / 64], slot)) {
if (!is_dl_slot(slot, &nr_mac->frame_structure)) {
LOG_D(NR_MAC, "Current slot %d is NOT DL slot, cannot schedule DCI0 for UL data\n", slot);
return;
}
......
......@@ -39,6 +39,14 @@ void set_cset_offset(uint16_t);
void get_K1_K2(int N1, int N2, int *K1, int *K2, int layers);
int get_NTN_Koffset(const NR_ServingCellConfigCommon_t *scc);
int get_first_ul_slot(const frame_structure_t *fs, bool mixed);
int get_ul_slots_per_period(const frame_structure_t *fs);
int get_ul_slots_per_frame(const frame_structure_t *fs);
int get_dl_slots_per_period(const frame_structure_t *fs);
int get_full_ul_slots_per_period(const frame_structure_t *fs);
int get_full_dl_slots_per_period(const frame_structure_t *fs);
int get_ul_slot_offset(const frame_structure_t *fs, int idx, bool count_mixed);
void mac_top_init_gNB(ngran_node_t node_type,
NR_ServingCellConfigCommon_t *scc,
NR_ServingCellConfig_t *scd,
......@@ -344,7 +352,9 @@ int nr_write_ce_dlsch_pdu(module_id_t module_idP,
int binomial(int n, int k);
bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot);
bool is_ul_slot(const slot_t slot, const frame_structure_t *fs);
bool is_dl_slot(const slot_t slot, const frame_structure_t *fs);
bool is_mixed_slot(const slot_t slot, const frame_structure_t *fs);
/* \brief Function to indicate a received SDU on ULSCH.
@param Mod_id Instance ID of gNB
......@@ -406,13 +416,10 @@ uint8_t get_mcs_from_cqi(int mcs_table, int cqi_table, int cqi_idx);
uint8_t get_dl_nrOfLayers(const NR_UE_sched_ctrl_t *sched_ctrl, const nr_dci_format_t dci_format);
void set_sched_pucch_list(NR_UE_sched_ctrl_t *sched_ctrl,
const NR_UE_UL_BWP_t *ul_bwp,
const NR_ServingCellConfigCommon_t *scc);
void free_sched_pucch_list(NR_UE_sched_ctrl_t *sched_ctrl);
int get_dl_tda(const gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *scc, int slot);
int get_ul_tda(gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *scc, int frame, int slot);
int get_dl_tda(const gNB_MAC_INST *nrmac, int slot);
int get_ul_tda(gNB_MAC_INST *nrmac, int frame, int slot);
int get_cce_index(const gNB_MAC_INST *nrmac,
const int CC_id,
......
......@@ -905,13 +905,10 @@ typedef struct gNB_MAC_INST_s {
NR_beam_info_t beam_info;
/// bitmap of DLSCH slots, can hold up to 160 slots
uint64_t dlsch_slot_bitmap[3];
/// bitmap of ULSCH slots, can hold up to 160 slots
uint64_t ulsch_slot_bitmap[3];
/// maximum number of slots before a UE will be scheduled ULSCH automatically
uint32_t ulsch_max_frame_inactivity;
/// instance of the frame structure configuration
frame_structure_t frame_structure;
/// DL preprocessor for differentiated scheduling
nr_pp_impl_dl pre_processor_dl;
......
This diff is collapsed.
......@@ -112,5 +112,6 @@ NR_CellGroupConfig_t *get_default_secondaryCellGroup(const NR_ServingCellConfigC
int uid);
NR_ReconfigurationWithSync_t *get_reconfiguration_with_sync(rnti_t rnti, uid_t uid, const NR_ServingCellConfigCommon_t *scc);
int get_tdd_period_idx(NR_TDD_UL_DL_ConfigCommon_t *tdd);
#endif
Active_gNBs = ( "gNB-OAI" );
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
gNBs =
(
{
////////// Identification parameters:
gNB_ID = 0xe00;
gNB_name = "gNB-OAI";
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
plmn_list = ({ mcc = 001; mnc = 01; mnc_length = 2; snssaiList = ({ sst = 1; sd = 1; }) });
nr_cellid = 12345678L;
////////// Physical parameters:
do_CSIRS = 1;
do_SRS = 1;
servingCellConfigCommon = (
{
# spCellConfigCommon
physCellId = 0;
# downlinkConfigCommon
# frequencyInfoDL
# this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP)
absoluteFrequencySSB = 641280;
dl_frequencyBand = 78;
# this is 3600 MHz
dl_absoluteFrequencyPointA = 640008;
# scs-SpecificCarrierList
dl_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
dl_subcarrierSpacing = 1;
dl_carrierBandwidth = 106;
# initialDownlinkBWP
# genericParameters
# this is RBstart=27,L=48 (275*(L-1))+RBstart
initialDLBWPlocationAndBandwidth = 28875;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialDLBWPsubcarrierSpacing = 1;
# pdcch-ConfigCommon
initialDLBWPcontrolResourceSetZero = 12;
initialDLBWPsearchSpaceZero = 0;
# uplinkConfigCommon
# frequencyInfoUL
ul_frequencyBand = 78;
# scs-SpecificCarrierList
ul_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
ul_subcarrierSpacing = 1;
ul_carrierBandwidth = 106;
pMax = 20;
# initialUplinkBWP
# genericParameters
initialULBWPlocationAndBandwidth = 28875;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialULBWPsubcarrierSpacing = 1;
# rach-ConfigCommon
# rach-ConfigGeneric
prach_ConfigurationIndex = 154;
# prach_msg1_FDM
# 0 = one, 1=two, 2=four, 3=eight
prach_msg1_FDM = 0;
prach_msg1_FrequencyStart = 0;
zeroCorrelationZoneConfig = 13;
preambleReceivedTargetPower = -96;
# preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
preambleTransMax = 6;
# powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
# ra_ReponseWindow
# 1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
# ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
# 1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;
# one (0..15) 4,8,12,16,...60,64
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 14;
# ra_ContentionResolutionTimer
# (0..7) 8,16,24,32,40,48,56,64
ra_ContentionResolutionTimer = 7;
rsrp_ThresholdSSB = 19;
# prach-RootSequenceIndex_PR
# 1 = 839, 2 = 139
prach_RootSequenceIndex_PR = 2;
prach_RootSequenceIndex = 1;
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precedence over the one derived from prach-ConfigIndex
msg1_SubcarrierSpacing = 1;
# restrictedSetConfig
# 0=unrestricted, 1=restricted type A, 2=restricted type B
restrictedSetConfig = 0;
msg3_DeltaPreamble = 1;
p0_NominalWithGrant = -90;
# pucch-ConfigCommon setup :
# pucchGroupHopping
# 0 = neither, 1= group hopping, 2=sequence hopping
pucchGroupHopping = 0;
hoppingId = 40;
p0_nominal = -90;
# ssb_PositionsInBurs_BitmapPR
# 1=short, 2=medium, 3=long
ssb_PositionsInBurst_PR = 2;
ssb_PositionsInBurst_Bitmap = 1;
# ssb_periodicityServingCell
# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1
ssb_periodicityServingCell = 2;
# dmrs_TypeA_position
# 0 = pos2, 1 = pos3
dmrs_TypeA_Position = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
subcarrierSpacing = 1;
# tdd-UL-DL-ConfigurationCommon
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
referenceSubcarrierSpacing = 1;
# pattern1
# dl_UL_TransmissionPeriodicity
# 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
# ext: 8=ms3, 9=ms4
dl_UL_TransmissionPeriodicity = 8;
nrofDownlinkSlots = 3;
nrofDownlinkSymbols = 6;
nrofUplinkSlots = 2;
nrofUplinkSymbols = 4;
# pattern2
pattern2: {
dl_UL_TransmissionPeriodicity2 = 4;
nrofDownlinkSlots2 = 4;
nrofDownlinkSymbols2 = 0;
nrofUplinkSlots2 = 0;
nrofUplinkSymbols2 = 0;
};
ssPBCH_BlockPower = -25;
});
# ------- SCTP definitions
SCTP :
{
# Number of streams to use in input/output
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
};
////////// AMF parameters:
amf_ip_address = ({ ipv4 = "192.168.70.132"; });
NETWORK_INTERFACES: {
GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.70.129";
GNB_IPV4_ADDRESS_FOR_NGU = "192.168.70.129";
GNB_PORT_FOR_S1U = 2152; # Spec 2152
};
}
);
MACRLCs = (
{
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
pusch_TargetSNRx10 = 150;
pucch_TargetSNRx10 = 200;
}
);
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
prach_dtx_threshold = 120;
pucch0_dtx_threshold = 100;
ofdm_offset_divisor = 8; # set this to UINT_MAX for offset 0
}
);
RUs = (
{
local_rf = "yes";
nb_tx = 1;
nb_rx = 1;
att_tx = 12;
att_rx = 12;
bands = [78];
max_pdschReferenceSignalPower = -27;
max_rxgain = 114;
eNB_instances = [0];
clock_src = "internal";
}
);
rfsimulator :
{
serveraddr = "server";
serverport = 4043;
options = (); # ("saviq"); or/and "chanmod"
modelname = "AWGN";
IQfile = "/tmp/rfsimulator.iqs";
};
security = {
# preferred ciphering algorithms
# the first one of the list that a UE supports is chosen
# valid values: nea0, nea1, nea2, nea3
ciphering_algorithms = ( "nea0" );
# preferred integrity algorithms
# the first one of the list that a UE supports is chosen
# valid values: nia0, nia1, nia2, nia3
integrity_algorithms = ( "nia2", "nia0" );
# setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter
# what 'ciphering_algorithms' configures; same thing for 'drb_integrity'
drb_ciphering = "yes";
drb_integrity = "no";
};
log_config :
{
global_log_level = "info";
hw_log_level = "info";
phy_log_level = "info";
mac_log_level = "info";
rlc_log_level = "info";
pdcp_log_level = "info";
rrc_log_level = "info";
ngap_log_level = "info";
f1ap_log_level = "info";
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment