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
This commit is contained in:
@@ -66,7 +66,7 @@ gNBs =
|
|||||||
initialULBWPsubcarrierSpacing = 1;
|
initialULBWPsubcarrierSpacing = 1;
|
||||||
#rach-ConfigCommon
|
#rach-ConfigCommon
|
||||||
#rach-ConfigGeneric
|
#rach-ConfigGeneric
|
||||||
prach_ConfigurationIndex = 98;
|
prach_ConfigurationIndex = 154;
|
||||||
#prach_msg1_FDM
|
#prach_msg1_FDM
|
||||||
#0 = one, 1=two, 2=four, 3=eight
|
#0 = one, 1=two, 2=four, 3=eight
|
||||||
prach_msg1_FDM = 0;
|
prach_msg1_FDM = 0;
|
||||||
@@ -133,11 +133,21 @@ gNBs =
|
|||||||
# pattern1
|
# pattern1
|
||||||
# dl_UL_TransmissionPeriodicity
|
# dl_UL_TransmissionPeriodicity
|
||||||
# 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
|
# 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
|
||||||
dl_UL_TransmissionPeriodicity = 6;
|
# ext: 8=ms3, 9=ms4
|
||||||
nrofDownlinkSlots = 7;
|
dl_UL_TransmissionPeriodicity = 8;
|
||||||
nrofDownlinkSymbols = 6;
|
nrofDownlinkSlots = 3;
|
||||||
nrofUplinkSlots = 2;
|
nrofDownlinkSymbols = 6;
|
||||||
nrofUplinkSymbols = 4;
|
nrofUplinkSlots = 2;
|
||||||
|
nrofUplinkSymbols = 4;
|
||||||
|
|
||||||
|
# pattern2
|
||||||
|
pattern2: {
|
||||||
|
dl_UL_TransmissionPeriodicity2 = 4;
|
||||||
|
nrofDownlinkSlots2 = 4;
|
||||||
|
nrofDownlinkSymbols2 = 0;
|
||||||
|
nrofUplinkSlots2 = 0;
|
||||||
|
nrofUplinkSymbols2 = 0;
|
||||||
|
};
|
||||||
|
|
||||||
ssPBCH_BlockPower = -25;
|
ssPBCH_BlockPower = -25;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,8 +21,8 @@
|
|||||||
|
|
||||||
-->
|
-->
|
||||||
<testCaseList>
|
<testCaseList>
|
||||||
<htmlTabRef>TEST-SA-FR1-SC-FDMA-B200</htmlTabRef>
|
<htmlTabRef>TEST-SA-FR1-SC-PATTERN2-FDMA-B200</htmlTabRef>
|
||||||
<htmlTabName>40 MHz TDD SA with SC-FDMA</htmlTabName>
|
<htmlTabName>40 MHz TDD (pattern2) SA with SC-FDMA</htmlTabName>
|
||||||
<htmlTabIcon>tasks</htmlTabIcon>
|
<htmlTabIcon>tasks</htmlTabIcon>
|
||||||
<TestCaseRequestedList>
|
<TestCaseRequestedList>
|
||||||
300000
|
300000
|
||||||
@@ -101,7 +101,7 @@
|
|||||||
</testCase>
|
</testCase>
|
||||||
<testCase id="230101">
|
<testCase id="230101">
|
||||||
<class>Deploy_Object</class>
|
<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>
|
<yaml_path>ci-scripts/yaml_files/sa_sc_b200_gnb</yaml_path>
|
||||||
<eNB_instance>0</eNB_instance>
|
<eNB_instance>0</eNB_instance>
|
||||||
<eNB_serverId>0</eNB_serverId>
|
<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;
|
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)
|
int get_dmrs_port(int nl, uint16_t dmrs_ports)
|
||||||
|
|||||||
@@ -122,6 +122,29 @@ typedef enum frequency_range_e {
|
|||||||
FR2
|
FR2
|
||||||
} frequency_range_t;
|
} 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 {
|
typedef struct {
|
||||||
/// Time shift in number of samples estimated based on DMRS-PDSCH/PUSCH
|
/// Time shift in number of samples estimated based on DMRS-PDSCH/PUSCH
|
||||||
int est_delay;
|
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);
|
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);
|
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 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);
|
int get_SLIV(uint8_t S, uint8_t L);
|
||||||
void get_coreset_rballoc(uint8_t *FreqDomainResource,int *n_rb,int *rb_offset);
|
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_m_srs(int c_srs, int b_srs);
|
||||||
unsigned short get_N_b_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 CEILIDIV(a,b) ((a+b-1)/b)
|
||||||
#define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1))
|
#define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1))
|
||||||
|
|
||||||
|
|||||||
+3
-1
@@ -24,7 +24,9 @@
|
|||||||
|
|
||||||
The following features are valid for the gNB and the 5G-NR UE.
|
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
|
* Normal CP
|
||||||
* Subcarrier spacings: 15 and 30kHz (FR1), 120kHz (FR2)
|
* Subcarrier spacings: 15 and 30kHz (FR1), 120kHz (FR2)
|
||||||
* Bandwidths: 10, 20, 40, 60, 80, 100MHz
|
* Bandwidths: 10, 20, 40, 60, 80, 100MHz
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 4.0 KiB |
@@ -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**)
|
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;
|
* `num_ulharq` (default 16): as `num_dlharq` for UL (other valid option is 32;
|
||||||
**32 is i Rel-17 feature**)
|
**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.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
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_CB 8
|
||||||
#define NFAPI_MAX_NUM_PRGS 1
|
#define NFAPI_MAX_NUM_PRGS 1
|
||||||
#define NFAPI_MAX_NUM_BG_IF 1
|
#define NFAPI_MAX_NUM_BG_IF 1
|
||||||
|
#define NFAPI_MAX_NUM_PERIODS 8
|
||||||
|
|
||||||
// Extension to the generic structures for single tlv values
|
// Extension to the generic structures for single tlv values
|
||||||
|
|
||||||
@@ -436,7 +437,10 @@ typedef struct
|
|||||||
|
|
||||||
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_max_tdd_periodicity_t* max_tdd_periodicity_list;
|
||||||
|
|
||||||
} nfapi_nr_tdd_table_t;
|
} 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);
|
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)
|
||||||
{
|
{
|
||||||
if(phy->state != NFAPI_PNF_PHY_RUNNING)
|
if(phy->state != NFAPI_PNF_PHY_RUNNING)
|
||||||
|
|||||||
@@ -44,108 +44,112 @@
|
|||||||
#define NR_TST_PHY_PRINTF(...)
|
#define NR_TST_PHY_PRINTF(...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*******************************************************************
|
/** @brief This function processes TDD dedicated configuration for NR
|
||||||
*
|
* by processing the tdd_slot_bitmap and period_cfg, and
|
||||||
* NAME : set_tdd_configuration
|
* allocates memory and fills max_num_of_symbol_per_slot_list
|
||||||
*
|
* in the nfapi config request (cfg)
|
||||||
* PARAMETERS : pointer to frame configuration
|
* @ref see TS 38.213 11.1 Slot configuration
|
||||||
*
|
* @param cfg NR config request structure pointer
|
||||||
* OUTPUT: table of uplink symbol for each slot for 2 frames
|
* @param fs TDD configuration pointer
|
||||||
*
|
* @returns void
|
||||||
* RETURN : 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)
|
||||||
*
|
|
||||||
* DESCRIPTION : generate bit map for uplink symbol for each slot for several frames
|
|
||||||
* see TS 38.213 11.1 Slot configuration
|
|
||||||
*
|
|
||||||
*********************************************************************/
|
|
||||||
|
|
||||||
int set_tdd_config_nr(nfapi_nr_config_request_scf_t *cfg,
|
|
||||||
int mu,
|
|
||||||
int nrofDownlinkSlots,
|
|
||||||
int nrofDownlinkSymbols,
|
|
||||||
int nrofUplinkSlots,
|
|
||||||
int nrofUplinkSymbols)
|
|
||||||
{
|
{
|
||||||
|
AssertFatal(fs != NULL, "frame_structure must be non-NULL");
|
||||||
|
|
||||||
int slot_number = 0;
|
int slot_number = 0;
|
||||||
int nb_periods_per_frame = get_nb_periods_per_frame(cfg->tdd_table.tdd_period.value);
|
int nb_slots_to_set = fs->numb_slots_frame;
|
||||||
int nb_slots_to_set = (1 << mu) * NR_NUMBER_OF_SUBFRAMES_PER_FRAME;
|
int slot_index = 0;
|
||||||
|
tdd_period_config_t *pc = &fs->period_cfg;
|
||||||
|
tdd_bitmap_t *tdd_slot_bitmap = pc->tdd_slot_bitmap;
|
||||||
|
|
||||||
int nb_slots_per_period = ((1 << mu) * NR_NUMBER_OF_SUBFRAMES_PER_FRAME) / nb_periods_per_frame;
|
LOG_I(NR_PHY,
|
||||||
|
"Set TDD Period Configuration: %d periods per frame, %d slots to be configured (%d DL, %d UL)\n",
|
||||||
if ((nrofDownlinkSymbols + nrofUplinkSymbols) == 0)
|
fs->numb_period_frame,
|
||||||
AssertFatal(nb_slots_per_period == (nrofDownlinkSlots + nrofUplinkSlots),
|
nb_slots_to_set,
|
||||||
"set_tdd_configuration_nr: given period is inconsistent with current tdd configuration, nrofDownlinkSlots %d, "
|
pc->num_dl_slots,
|
||||||
"nrofUplinkSlots %d, nb_slots_per_period %d \n",
|
pc->num_ul_slots);
|
||||||
nrofDownlinkSlots,
|
|
||||||
nrofUplinkSlots,
|
|
||||||
nb_slots_per_period);
|
|
||||||
else {
|
|
||||||
AssertFatal(nrofDownlinkSymbols + nrofUplinkSymbols < 14,
|
|
||||||
"illegal symbol configuration DL %d, UL %d\n",
|
|
||||||
nrofDownlinkSymbols,
|
|
||||||
nrofUplinkSymbols);
|
|
||||||
AssertFatal(nb_slots_per_period == (nrofDownlinkSlots + nrofUplinkSlots + 1),
|
|
||||||
"set_tdd_configuration_nr: given period is inconsistent with current tdd configuration, nrofDownlinkSlots %d, "
|
|
||||||
"nrofUplinkSlots %d, nrofMixed slots 1, nb_slots_per_period %d \n",
|
|
||||||
nrofDownlinkSlots,
|
|
||||||
nrofUplinkSlots,
|
|
||||||
nb_slots_per_period);
|
|
||||||
}
|
|
||||||
|
|
||||||
cfg->tdd_table.max_tdd_periodicity_list = calloc(nb_slots_to_set, sizeof(nfapi_nr_max_tdd_periodicity_t));
|
|
||||||
|
|
||||||
|
// Allocate memory formax_num_of_symbol_per_slot_list items
|
||||||
|
cfg->tdd_table.max_tdd_periodicity_list = calloc_or_fail(nb_slots_to_set, sizeof(nfapi_nr_max_tdd_periodicity_t));
|
||||||
for (int slot = 0; slot < nb_slots_to_set; slot++) {
|
for (int slot = 0; slot < nb_slots_to_set; slot++) {
|
||||||
nfapi_nr_max_tdd_periodicity_t *p_list = &cfg->tdd_table.max_tdd_periodicity_list[slot];
|
nfapi_nr_max_tdd_periodicity_t *p_list = &cfg->tdd_table.max_tdd_periodicity_list[slot];
|
||||||
p_list->max_num_of_symbol_per_slot_list =
|
p_list->max_num_of_symbol_per_slot_list =
|
||||||
calloc(NR_NUMBER_OF_SYMBOLS_PER_SLOT, sizeof(*p_list->max_num_of_symbol_per_slot_list));
|
calloc_or_fail(NR_NUMBER_OF_SYMBOLS_PER_SLOT, sizeof(*p_list->max_num_of_symbol_per_slot_list));
|
||||||
for (int sym = 0; sym < NR_NUMBER_OF_SYMBOLS_PER_SLOT; sym++) {
|
for (int sym = 0; sym < NR_NUMBER_OF_SYMBOLS_PER_SLOT; sym++) {
|
||||||
// for each symbol, assign the TLV tag for usage when packing
|
// for each symbol, assign the TLV tag for usage when packing
|
||||||
p_list->max_num_of_symbol_per_slot_list[sym].slot_config.tl.tag = NFAPI_NR_CONFIG_SLOT_CONFIG_TAG;
|
p_list->max_num_of_symbol_per_slot_list[sym].slot_config.tl.tag = NFAPI_NR_CONFIG_SLOT_CONFIG_TAG;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Loop through all periods to be configured
|
||||||
while (slot_number != nb_slots_to_set) {
|
while (slot_number != nb_slots_to_set) {
|
||||||
if (nrofDownlinkSlots != 0) {
|
slot_index = get_slot_idx_in_period(slot_number, fs);
|
||||||
for (int sym = 0; sym < nrofDownlinkSlots * NR_NUMBER_OF_SYMBOLS_PER_SLOT; sym++) {
|
/* Fill max_tdd_periodicity_list */
|
||||||
cfg->tdd_table.max_tdd_periodicity_list[slot_number]
|
nfapi_nr_max_tdd_periodicity_t *list = &cfg->tdd_table.max_tdd_periodicity_list[slot_number];
|
||||||
.max_num_of_symbol_per_slot_list[sym % NR_NUMBER_OF_SYMBOLS_PER_SLOT]
|
// FULL DOWNLINK SLOTS
|
||||||
.slot_config.value = 0;
|
if (tdd_slot_bitmap[slot_index].slot_type == TDD_NR_DOWNLINK_SLOT) {
|
||||||
|
for (int sym = 0; sym < NR_NUMBER_OF_SYMBOLS_PER_SLOT; sym++) {
|
||||||
if ((sym + 1) % NR_NUMBER_OF_SYMBOLS_PER_SLOT == 0)
|
list->max_num_of_symbol_per_slot_list[sym % NR_NUMBER_OF_SYMBOLS_PER_SLOT].slot_config.value = 0;
|
||||||
|
if ((sym + 1) % NR_NUMBER_OF_SYMBOLS_PER_SLOT == 0) {
|
||||||
slot_number++;
|
slot_number++;
|
||||||
|
list += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// FLEXIBLE SLOTS
|
||||||
if (nrofDownlinkSymbols != 0 || nrofUplinkSymbols != 0) {
|
if (tdd_slot_bitmap[slot_index].slot_type == TDD_NR_MIXED_SLOT) {
|
||||||
for (int sym = 0; sym < nrofDownlinkSymbols; sym++) {
|
int nrofDLSymbolsInSlot = tdd_slot_bitmap[slot_index].num_dl_symbols;
|
||||||
cfg->tdd_table.max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[sym].slot_config.value = 0;
|
int nrofULSymbolsInSlot = tdd_slot_bitmap[slot_index].num_ul_symbols;
|
||||||
|
AssertFatal(nrofDLSymbolsInSlot + nrofULSymbolsInSlot < NR_NUMBER_OF_SYMBOLS_PER_SLOT,
|
||||||
|
"illegal symbol configuration DL %d, UL %d\n",
|
||||||
|
nrofDLSymbolsInSlot,
|
||||||
|
nrofULSymbolsInSlot);
|
||||||
|
// DL Symbols
|
||||||
|
for (int sym = 0; sym < nrofDLSymbolsInSlot; sym++) {
|
||||||
|
list->max_num_of_symbol_per_slot_list[sym].slot_config.value = 0;
|
||||||
}
|
}
|
||||||
|
// Flexible Symbols
|
||||||
for (int sym = nrofDownlinkSymbols; sym < NR_NUMBER_OF_SYMBOLS_PER_SLOT - nrofUplinkSymbols; sym++) {
|
for (int sym = nrofDLSymbolsInSlot; sym < NR_NUMBER_OF_SYMBOLS_PER_SLOT - nrofULSymbolsInSlot; sym++) {
|
||||||
cfg->tdd_table.max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[sym].slot_config.value = 2;
|
list->max_num_of_symbol_per_slot_list[sym].slot_config.value = 2;
|
||||||
}
|
}
|
||||||
|
// UL Symbols
|
||||||
for (int sym = NR_NUMBER_OF_SYMBOLS_PER_SLOT - nrofUplinkSymbols; sym < NR_NUMBER_OF_SYMBOLS_PER_SLOT; sym++) {
|
for (int sym = NR_NUMBER_OF_SYMBOLS_PER_SLOT - nrofULSymbolsInSlot; sym < NR_NUMBER_OF_SYMBOLS_PER_SLOT; sym++) {
|
||||||
cfg->tdd_table.max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[sym].slot_config.value = 1;
|
list->max_num_of_symbol_per_slot_list[sym].slot_config.value = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
slot_number++;
|
slot_number++;
|
||||||
|
list += 1;
|
||||||
}
|
}
|
||||||
|
// FULL UPLINK SLOTS
|
||||||
if (nrofUplinkSlots != 0) {
|
if (tdd_slot_bitmap[slot_index].slot_type == TDD_NR_UPLINK_SLOT) {
|
||||||
for (int sym = 0; sym < nrofUplinkSlots * NR_NUMBER_OF_SYMBOLS_PER_SLOT; sym++) {
|
for (int sym = 0; sym < NR_NUMBER_OF_SYMBOLS_PER_SLOT; sym++) {
|
||||||
cfg->tdd_table.max_tdd_periodicity_list[slot_number]
|
list->max_num_of_symbol_per_slot_list[sym % NR_NUMBER_OF_SYMBOLS_PER_SLOT].slot_config.value = 1;
|
||||||
.max_num_of_symbol_per_slot_list[sym % NR_NUMBER_OF_SYMBOLS_PER_SLOT]
|
if ((sym + 1) % NR_NUMBER_OF_SYMBOLS_PER_SLOT == 0) {
|
||||||
.slot_config.value = 1;
|
|
||||||
|
|
||||||
if ((sym + 1) % NR_NUMBER_OF_SYMBOLS_PER_SLOT == 0)
|
|
||||||
slot_number++;
|
slot_number++;
|
||||||
|
list += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Dump 1 period on the output
|
||||||
return (nb_periods_per_frame);
|
for (int s = 0; s < fs->numb_slots_period; s++) {
|
||||||
|
if (tdd_slot_bitmap[s].slot_type == TDD_NR_MIXED_SLOT) {
|
||||||
|
char flexi_slot[NR_NUMBER_OF_SYMBOLS_PER_SLOT + 1];
|
||||||
|
memset(flexi_slot, 0, sizeof(flexi_slot));
|
||||||
|
for (int symb = 0; symb < NR_NUMBER_OF_SYMBOLS_PER_SLOT; symb++) {
|
||||||
|
uint8_t val = cfg->tdd_table.max_tdd_periodicity_list[s].max_num_of_symbol_per_slot_list[symb].slot_config.value;
|
||||||
|
char *symb_type_s[] = {"D", "U", "F"};
|
||||||
|
flexi_slot[symb] = *symb_type_s[val];
|
||||||
|
}
|
||||||
|
flexi_slot[NR_NUMBER_OF_SYMBOLS_PER_SLOT] = '\0';
|
||||||
|
LOG_I(NR_PHY, "TDD period configuration: slot %d is FLEXIBLE: %s\n", s, flexi_slot);
|
||||||
|
} else {
|
||||||
|
LOG_I(NR_PHY,
|
||||||
|
"TDD period configuration: slot %d is %s\n",
|
||||||
|
s,
|
||||||
|
tdd_slot_bitmap[s].slot_type == TDD_NR_DOWNLINK_SLOT ? "DOWNLINK" : "UPLINK");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
@@ -389,3 +393,48 @@ void free_tdd_configuration_dedicated_nr(NR_DL_FRAME_PARMS *frame_parms) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void do_tdd_config_sim(PHY_VARS_gNB *gNB, int mu)
|
||||||
|
{
|
||||||
|
frame_structure_t fs = {.is_tdd = true};
|
||||||
|
fs.numb_slots_frame = (1 << mu) * NR_NUMBER_OF_SUBFRAMES_PER_FRAME;
|
||||||
|
fs.numb_period_frame = get_nb_periods_per_frame(gNB->gNB_config.tdd_table.tdd_period.value);
|
||||||
|
fs.numb_slots_period = fs.numb_slots_frame / fs.numb_period_frame;
|
||||||
|
tdd_period_config_t *pc = &fs.period_cfg;
|
||||||
|
// Set DL/UL slots
|
||||||
|
switch (mu)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
pc->num_dl_slots = 3;
|
||||||
|
pc->num_ul_slots = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
pc->num_dl_slots = 7;
|
||||||
|
pc->num_ul_slots = 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
pc->num_dl_slots = 27;
|
||||||
|
pc->num_ul_slots = 12;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < pc->num_dl_slots; i++) {
|
||||||
|
pc->tdd_slot_bitmap[i].slot_type = TDD_NR_DOWNLINK_SLOT;
|
||||||
|
pc->tdd_slot_bitmap[i].num_dl_symbols = 0;
|
||||||
|
pc->tdd_slot_bitmap[i].num_ul_symbols = 0;
|
||||||
|
}
|
||||||
|
for (int i = pc->num_dl_slots; i < fs.numb_slots_period - pc->num_ul_slots; i++) {
|
||||||
|
pc->tdd_slot_bitmap[i].slot_type = TDD_NR_MIXED_SLOT;
|
||||||
|
pc->tdd_slot_bitmap[i].num_dl_symbols = 6;
|
||||||
|
pc->tdd_slot_bitmap[i].num_ul_symbols = 4;
|
||||||
|
}
|
||||||
|
for (int i = pc->num_ul_slots; i < fs.numb_slots_period; i++) {
|
||||||
|
pc->tdd_slot_bitmap[i].slot_type = TDD_NR_UPLINK_SLOT;
|
||||||
|
pc->tdd_slot_bitmap[i].num_dl_symbols = 0;
|
||||||
|
pc->tdd_slot_bitmap[i].num_ul_symbols = 0;
|
||||||
|
}
|
||||||
|
set_tdd_config_nr(&gNB->gNB_config, &fs);
|
||||||
|
}
|
||||||
|
|||||||
@@ -36,18 +36,16 @@
|
|||||||
|
|
||||||
/*************** FUNCTIONS *****************************************/
|
/*************** FUNCTIONS *****************************************/
|
||||||
|
|
||||||
/** \brief This function processes tdd dedicated configuration for nr
|
/** @brief This function processes TDD dedicated configuration for NR
|
||||||
* @param frame_parms NR DL Frame parameters
|
* by processing the tdd_slot_bitmap and period_cfg, and
|
||||||
* @param dl_UL_TransmissionPeriodicity periodicity
|
* allocates memory and fills max_num_of_symbol_per_slot_list
|
||||||
* @param nrofDownlinkSlots number of downlink slots
|
* in the nfapi config request (cfg)
|
||||||
* @param nrofDownlinkSymbols number of downlink symbols
|
* @param cfg NR config request structure pointer
|
||||||
* @param nrofUplinkSlots number of uplink slots
|
* @param fs frame structure pointer
|
||||||
* @param nrofUplinkSymbols number of uplink symbols
|
* @returns nb_periods_per_frame if TDD has been properly configurated
|
||||||
@returns 0 if tdd dedicated configuration has been properly set or -1 on error with message */
|
* -1 tdd configuration can not be done
|
||||||
|
*/
|
||||||
int set_tdd_config_nr(nfapi_nr_config_request_scf_t *cfg, int mu,
|
void set_tdd_config_nr(nfapi_nr_config_request_scf_t *cfg, frame_structure_t *fs);
|
||||||
int nrofDownlinkSlots, int nrofDownlinkSymbols,
|
|
||||||
int nrofUplinkSlots, int nrofUplinkSymbols);
|
|
||||||
|
|
||||||
/** \brief This function adds a slot configuration to current dedicated configuration for nr
|
/** \brief This function adds a slot configuration to current dedicated configuration for nr
|
||||||
* @param frame_parms NR DL Frame parameters
|
* @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);
|
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 */
|
#endif /* PHY_FRAME_CONFIG_NR_H */
|
||||||
|
|
||||||
|
|||||||
@@ -388,8 +388,9 @@ int main(int argc, char **argv)
|
|||||||
frame_parms->Ncp = extended_prefix_flag ? EXTENDED : NORMAL;
|
frame_parms->Ncp = extended_prefix_flag ? EXTENDED : NORMAL;
|
||||||
crcTableInit();
|
crcTableInit();
|
||||||
nr_phy_config_request_sim(gNB, N_RB_DL, N_RB_DL, mu, Nid_cell,SSB_positions);
|
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;
|
// TDD configuration
|
||||||
set_tdd_config_nr(&gNB->gNB_config, mu, 7, 6, 2, 4);
|
gNB->gNB_config.tdd_table.tdd_period.value = 6;
|
||||||
|
do_tdd_config_sim(gNB, mu);
|
||||||
phy_init_nr_gNB(gNB);
|
phy_init_nr_gNB(gNB);
|
||||||
//init_eNB_afterRU();
|
//init_eNB_afterRU();
|
||||||
frame_length_complex_samples = frame_parms->samples_per_subframe;
|
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
|
/* the following might override the table that is mandated by RRC
|
||||||
* configuration */
|
* configuration */
|
||||||
current_BWP->mcsTableIdx = g_mcsTableIdx;
|
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");
|
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,
|
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;
|
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);
|
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;
|
gNB->gNB_config.tdd_table.tdd_period.value = 6;
|
||||||
if (mu == 0)
|
do_tdd_config_sim(gNB, mu);
|
||||||
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);
|
|
||||||
phy_init_nr_gNB(gNB);
|
phy_init_nr_gNB(gNB);
|
||||||
frame_parms->ssb_start_subcarrier = 12 * gNB->gNB_config.ssb_table.ssb_offset_point_a.value + ssb_subcarrier_offset;
|
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");
|
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));
|
memcpy((void*)&ru->config,(void*)&RC.gNB[0]->gNB_config,sizeof(ru->config));
|
||||||
RC.nb_nr_L1_inst=1;
|
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);
|
phy_init_nr_gNB(gNB);
|
||||||
nr_phy_init_RU(ru);
|
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_tx_ant.value = n_tx;
|
||||||
cfg->carrier_config.num_rx_ant.value = n_rx;
|
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);
|
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;
|
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);
|
phy_init_nr_gNB(gNB);
|
||||||
/* RU handles rxdataF, and gNB just has a pointer. Here, we don't have an RU,
|
/* 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. */
|
* 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;
|
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);
|
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;
|
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);
|
phy_init_nr_gNB(gNB);
|
||||||
|
|
||||||
//configure UE
|
//configure UE
|
||||||
|
|||||||
@@ -60,11 +60,11 @@ bool read_mac_sm(void* data)
|
|||||||
rd->dl_aggr_tbs = UE->mac_stats.dl.total_bytes;
|
rd->dl_aggr_tbs = UE->mac_stats.dl.total_bytes;
|
||||||
rd->ul_aggr_tbs = UE->mac_stats.ul.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_curr_tbs = UE->mac_stats.dl.current_bytes;
|
||||||
rd->dl_sched_rb = UE->mac_stats.dl.current_rbs;
|
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_curr_tbs = UE->mac_stats.ul.current_bytes;
|
||||||
rd->ul_sched_rb = sched_ctrl->sched_pusch.rbSize;
|
rd->ul_sched_rb = sched_ctrl->sched_pusch.rbSize;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,6 +116,7 @@
|
|||||||
#define GNB_CONFIG_STRING_NROFDOWNLINKSYMBOLS "nrofDownlinkSymbols"
|
#define GNB_CONFIG_STRING_NROFDOWNLINKSYMBOLS "nrofDownlinkSymbols"
|
||||||
#define GNB_CONFIG_STRING_NROFUPLINKSLOTS "nrofUplinkSlots"
|
#define GNB_CONFIG_STRING_NROFUPLINKSLOTS "nrofUplinkSlots"
|
||||||
#define GNB_CONFIG_STRING_NROFUPLINKSYMBOLS "nrofUplinkSymbols"
|
#define GNB_CONFIG_STRING_NROFUPLINKSYMBOLS "nrofUplinkSymbols"
|
||||||
|
#define GNB_CONFIG_STRING_PATTERN2 "pattern2"
|
||||||
#define GNB_CONFIG_STRING_DLULTRANSMISSIONPERIODICITY2 "dl_UL_TransmissionPeriodicity2"
|
#define GNB_CONFIG_STRING_DLULTRANSMISSIONPERIODICITY2 "dl_UL_TransmissionPeriodicity2"
|
||||||
#define GNB_CONFIG_STRING_NROFDOWNLINKSLOTS2 "nrofDownlinkSlots2"
|
#define GNB_CONFIG_STRING_NROFDOWNLINKSLOTS2 "nrofDownlinkSlots2"
|
||||||
#define GNB_CONFIG_STRING_NROFDOWNLINKSYMBOLS2 "nrofDownlinkSymbols2"
|
#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_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_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_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_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_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}, \
|
{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_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}}
|
{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 */
|
/* 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->ssb_periodicityServingCell = calloc_or_fail(1, sizeof(*scc->ssb_periodicityServingCell));
|
||||||
scc->ssbSubcarrierSpacing = calloc_or_fail(1, sizeof(*scc->ssbSubcarrierSpacing));
|
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 = 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 = calloc_or_fail(1, sizeof(*scc->downlinkConfigCommon));
|
||||||
scc->downlinkConfigCommon->frequencyInfoDL = calloc_or_fail(1, sizeof(*scc->downlinkConfigCommon->frequencyInfoDL));
|
scc->downlinkConfigCommon->frequencyInfoDL = calloc_or_fail(1, sizeof(*scc->downlinkConfigCommon->frequencyInfoDL));
|
||||||
scc->downlinkConfigCommon->initialDownlinkBWP = calloc_or_fail(1, sizeof(*scc->downlinkConfigCommon->initialDownlinkBWP));
|
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;
|
p1->nrofUplinkSymbols = 4;
|
||||||
|
|
||||||
struct NR_TDD_UL_DL_Pattern *p2 = tdd_UL_DL_ConfigurationCommon->pattern2;
|
struct NR_TDD_UL_DL_Pattern *p2 = tdd_UL_DL_ConfigurationCommon->pattern2;
|
||||||
p2->dl_UL_TransmissionPeriodicity = 321;
|
if (p2) {
|
||||||
p2->nrofDownlinkSlots = -1;
|
p2->dl_UL_TransmissionPeriodicity = 321;
|
||||||
p2->nrofDownlinkSymbols = -1;
|
p2->nrofDownlinkSlots = -1;
|
||||||
p2->nrofUplinkSlots = -1;
|
p2->nrofDownlinkSymbols = -1;
|
||||||
p2->nrofUplinkSymbols = -1;
|
p2->nrofUplinkSlots = -1;
|
||||||
|
p2->nrofUplinkSymbols = -1;
|
||||||
|
}
|
||||||
|
|
||||||
scc->ss_PBCH_BlockPower = 20;
|
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)
|
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);
|
ASN_STRUCT_FREE(asn_DEF_NR_TDD_UL_DL_ConfigCommon, scc->tdd_UL_DL_ConfigurationCommon);
|
||||||
scc->tdd_UL_DL_ConfigurationCommon = NULL;
|
scc->tdd_UL_DL_ConfigurationCommon = NULL;
|
||||||
} else { // TDD
|
} else { // TDD
|
||||||
if (scc->tdd_UL_DL_ConfigurationCommon->pattern2->dl_UL_TransmissionPeriodicity > 320 ) {
|
fix_tdd_pattern(scc);
|
||||||
free(scc->tdd_UL_DL_ConfigurationCommon->pattern2);
|
|
||||||
scc->tdd_UL_DL_ConfigurationCommon->pattern2 = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((int)*scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing == -1) {
|
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)
|
static NR_ServingCellConfigCommon_t *get_scc_config(configmodule_interface_t *cfg, int minRXTXTIME)
|
||||||
{
|
{
|
||||||
NR_ServingCellConfigCommon_t *scc = calloc_or_fail(1, sizeof(*scc));
|
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);
|
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, SCCsParams, sizeofArray(SCCsParams), aprefix);
|
||||||
config_get(cfg, MsgASCCsParams, sizeofArray(MsgASCCsParams), 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;
|
struct NR_FrequencyInfoDL *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL;
|
||||||
LOG_I(RRC,
|
LOG_I(RRC,
|
||||||
"Read in ServingCellConfigCommon (PhysCellId %d, ABSFREQSSB %d, DLBand %d, ABSFREQPOINTA %d, DLBW "
|
"Read in ServingCellConfigCommon (PhysCellId %d, ABSFREQSSB %d, DLBand %d, ABSFREQPOINTA %d, DLBW "
|
||||||
|
|||||||
@@ -279,6 +279,257 @@ nfapi_nr_pm_list_t init_DL_MIMO_codebook(gNB_MAC_INST *gNB, nr_pdsch_AntennaPort
|
|||||||
return mat;
|
return mat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Configures the TDD period, including bitmap, in the frame structure
|
||||||
|
*
|
||||||
|
* This function sets the TDD period configuration for DL, UL, and mixed slots in
|
||||||
|
* the specified frame structure instance, according to the given pattern, and
|
||||||
|
* updates the bitmap.
|
||||||
|
*
|
||||||
|
* @param pattern NR_TDD_UL_DL_Pattern_t configuration containing TDD slots and symbols configuration
|
||||||
|
* @param fs frame_structure_t pointer
|
||||||
|
* @param curr_total_slot current position in the slot bitmap to start from
|
||||||
|
*
|
||||||
|
* @return Number of slots in the configured TDD period
|
||||||
|
*/
|
||||||
|
static uint8_t set_tdd_bmap_period(NR_TDD_UL_DL_Pattern_t *pattern, tdd_period_config_t *pc, int8_t curr_total_slot)
|
||||||
|
{
|
||||||
|
int8_t n_dl_slot = pattern->nrofDownlinkSlots;
|
||||||
|
int8_t n_ul_slot = pattern->nrofUplinkSlots;
|
||||||
|
int8_t n_dl_symbols = pattern->nrofDownlinkSymbols;
|
||||||
|
int8_t n_ul_symbols = pattern->nrofUplinkSymbols;
|
||||||
|
|
||||||
|
// Total slots in the period: if DL/UL symbols are present, is mixed slot
|
||||||
|
const bool has_mixed_slot = (n_ul_symbols + n_dl_symbols) > 0;
|
||||||
|
int8_t total_slot = has_mixed_slot ? n_dl_slot + n_ul_slot + 1 : n_dl_slot + n_ul_slot;
|
||||||
|
|
||||||
|
/** Update TDD period configuration:
|
||||||
|
* mixed slots with DL symbols are counted as DL slots
|
||||||
|
* mixed slots with UL symbols are counted as UL slots */
|
||||||
|
pc->num_dl_slots += (n_dl_slot + (n_dl_symbols > 0));
|
||||||
|
pc->num_ul_slots += (n_ul_slot + (n_ul_symbols > 0));
|
||||||
|
|
||||||
|
// Populate the slot bitmap for each slot in the TDD period
|
||||||
|
for (int i = 0; i < total_slot; i++) {
|
||||||
|
tdd_bitmap_t *bitmap = &pc->tdd_slot_bitmap[i + curr_total_slot];
|
||||||
|
if (i < n_dl_slot)
|
||||||
|
bitmap->slot_type = TDD_NR_DOWNLINK_SLOT;
|
||||||
|
else if ((i == n_dl_slot) && has_mixed_slot) {
|
||||||
|
bitmap->slot_type = TDD_NR_MIXED_SLOT;
|
||||||
|
bitmap->num_dl_symbols = n_dl_symbols;
|
||||||
|
bitmap->num_ul_symbols = n_ul_symbols;
|
||||||
|
} else if (n_ul_slot)
|
||||||
|
bitmap->slot_type = TDD_NR_UPLINK_SLOT;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_I(NR_MAC,
|
||||||
|
"Set TDD configuration period to: %d DL slots, %d UL slots, %d slots per period (NR_TDD_UL_DL_Pattern is %d DL slots, %d "
|
||||||
|
"UL slots, %d DL symbols, %d UL symbols)\n",
|
||||||
|
pc->num_dl_slots,
|
||||||
|
pc->num_ul_slots,
|
||||||
|
total_slot,
|
||||||
|
n_dl_slot,
|
||||||
|
n_ul_slot,
|
||||||
|
n_dl_symbols,
|
||||||
|
n_ul_symbols);
|
||||||
|
|
||||||
|
return total_slot;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Configures TDD patterns (1 or 2) in the frame structure
|
||||||
|
*
|
||||||
|
* This function sets up the TDD configuration in the frame structure by applying
|
||||||
|
* DL and UL patterns as defined in NR_TDD_UL_DL_ConfigCommon.
|
||||||
|
* It handles both TDD pattern1 and pattern2.
|
||||||
|
*
|
||||||
|
* @param tdd NR_TDD_UL_DL_ConfigCommon_t pointer containing pattern1 and pattern2
|
||||||
|
* @param fs Pointer to the frame structure to update with the configured TDD patterns.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
static void config_tdd_patterns(NR_TDD_UL_DL_ConfigCommon_t *tdd, frame_structure_t *fs)
|
||||||
|
{
|
||||||
|
int num_of_patterns = 1;
|
||||||
|
uint8_t nb_slots_p2 = 0;
|
||||||
|
// Reset num dl/ul slots
|
||||||
|
tdd_period_config_t *pc = &fs->period_cfg;
|
||||||
|
pc->num_dl_slots = 0;
|
||||||
|
pc->num_ul_slots = 0;
|
||||||
|
// Pattern1
|
||||||
|
uint8_t nb_slots_p1 = set_tdd_bmap_period(&tdd->pattern1, pc, 0);
|
||||||
|
// Pattern2
|
||||||
|
if (tdd->pattern2) {
|
||||||
|
num_of_patterns++;
|
||||||
|
nb_slots_p2 = set_tdd_bmap_period(tdd->pattern2, pc, nb_slots_p1);
|
||||||
|
}
|
||||||
|
LOG_I(NR_MAC,
|
||||||
|
"Configured %d TDD patterns (total slots: pattern1 = %d, pattern2 = %d)\n",
|
||||||
|
num_of_patterns,
|
||||||
|
nb_slots_p1,
|
||||||
|
nb_slots_p2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the first UL slot index in period
|
||||||
|
* @param fs frame structure
|
||||||
|
* @param mixed indicates whether to include in the count also mixed slot with UL symbols or only full UL slot
|
||||||
|
* @return slot index
|
||||||
|
*/
|
||||||
|
int get_first_ul_slot(const frame_structure_t *fs, bool mixed)
|
||||||
|
{
|
||||||
|
DevAssert(fs);
|
||||||
|
|
||||||
|
if (fs->is_tdd) {
|
||||||
|
for (int i = 0; i < fs->numb_slots_period; i++) {
|
||||||
|
if ((mixed && is_ul_slot(i, fs)) || fs->period_cfg.tdd_slot_bitmap[i].slot_type == TDD_NR_UPLINK_SLOT) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0; // FDD
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get number of DL slots per period (full DL slots + mixed slots with DL symbols)
|
||||||
|
*/
|
||||||
|
int get_dl_slots_per_period(const frame_structure_t *fs)
|
||||||
|
{
|
||||||
|
return fs->is_tdd ? fs->period_cfg.num_dl_slots : fs->numb_slots_frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get number of UL slots per period (full UL slots + mixed slots with UL symbols)
|
||||||
|
*/
|
||||||
|
int get_ul_slots_per_period(const frame_structure_t *fs)
|
||||||
|
{
|
||||||
|
return fs->is_tdd ? fs->period_cfg.num_ul_slots : fs->numb_slots_frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get number of full UL slots per period
|
||||||
|
* @param fs Pointer to the frame structure
|
||||||
|
* @return Number of full UL slots
|
||||||
|
*/
|
||||||
|
int get_full_ul_slots_per_period(const frame_structure_t *fs)
|
||||||
|
{
|
||||||
|
DevAssert(fs);
|
||||||
|
|
||||||
|
if (!fs->is_tdd)
|
||||||
|
return fs->numb_slots_frame;
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < fs->numb_slots_period; i++)
|
||||||
|
if (fs->period_cfg.tdd_slot_bitmap[i].slot_type == TDD_NR_UPLINK_SLOT)
|
||||||
|
count++;
|
||||||
|
|
||||||
|
LOG_D(NR_MAC, "Full UL slots in TDD period: %d\n", count);
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get number of full DL slots per period
|
||||||
|
* @param fs Pointer to the frame structure
|
||||||
|
* @return Number of full DL slots
|
||||||
|
*/
|
||||||
|
int get_full_dl_slots_per_period(const frame_structure_t *fs)
|
||||||
|
{
|
||||||
|
DevAssert(fs);
|
||||||
|
|
||||||
|
if (!fs->is_tdd)
|
||||||
|
return fs->numb_slots_frame;
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < fs->numb_slots_period; i++)
|
||||||
|
if (fs->period_cfg.tdd_slot_bitmap[i].slot_type == TDD_NR_DOWNLINK_SLOT)
|
||||||
|
count++;
|
||||||
|
|
||||||
|
LOG_D(NR_MAC, "Full DL slots in TDD period: %d\n", count);
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get number of UL slots per frame
|
||||||
|
*/
|
||||||
|
int get_ul_slots_per_frame(const frame_structure_t *fs)
|
||||||
|
{
|
||||||
|
return fs->is_tdd ? fs->numb_period_frame * get_ul_slots_per_period(fs) : fs->numb_slots_frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the nth UL slot offset for UE index idx in a TDD period using the frame structure bitmap
|
||||||
|
* @param fs frame structure
|
||||||
|
* @param idx UE index
|
||||||
|
* @param count_mixed indicates whether counting mixed slot with UL symbols (e.g. for SRS) or only full UL slots
|
||||||
|
* @return slot index offset
|
||||||
|
*/
|
||||||
|
int get_ul_slot_offset(const frame_structure_t *fs, int idx, bool count_mixed)
|
||||||
|
{
|
||||||
|
DevAssert(fs);
|
||||||
|
|
||||||
|
// FDD
|
||||||
|
if (!fs->is_tdd)
|
||||||
|
return idx;
|
||||||
|
|
||||||
|
// UL slots indexes in period
|
||||||
|
int ul_slot_idxs[fs->numb_slots_period];
|
||||||
|
int ul_slot_count = 0;
|
||||||
|
|
||||||
|
/* Populate the indices of UL slots in the TDD period from the bitmap
|
||||||
|
count also mixed slots with UL symbols if flag count_mixed is present */
|
||||||
|
for (int i = 0; i < fs->numb_slots_period; i++) {
|
||||||
|
if ((count_mixed && is_ul_slot(i, fs)) || fs->period_cfg.tdd_slot_bitmap[i].slot_type == TDD_NR_UPLINK_SLOT) {
|
||||||
|
ul_slot_idxs[ul_slot_count++] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute slot index offset
|
||||||
|
int period_idx = idx / ul_slot_count; // wrap up the count of complete TDD periods spanned by the index
|
||||||
|
int ul_slot_idx_in_period = idx % ul_slot_count; // wrap up the UL slot index within the current TDD period
|
||||||
|
|
||||||
|
return ul_slot_idxs[ul_slot_idx_in_period] + period_idx * fs->numb_slots_period;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Configures the frame structure and the NFAPI config request
|
||||||
|
* depending on the duplex mode. If TDD, does the TDD patterns
|
||||||
|
* and TDD periods configuration.
|
||||||
|
*
|
||||||
|
* @param mu numerology
|
||||||
|
* @param scc pointer to scc
|
||||||
|
* @param cfg pointer to NFAPI config request
|
||||||
|
* @param fs pointer to the frame structure to update
|
||||||
|
*
|
||||||
|
* @return Number of periods in frame
|
||||||
|
*/
|
||||||
|
static int config_frame_structure(int mu,
|
||||||
|
NR_ServingCellConfigCommon_t *scc,
|
||||||
|
nfapi_nr_config_request_scf_t *cfg,
|
||||||
|
frame_structure_t *fs)
|
||||||
|
{
|
||||||
|
fs->numb_slots_frame = nr_slots_per_frame[mu];
|
||||||
|
if (cfg->cell_config.frame_duplex_type.value == TDD) {
|
||||||
|
cfg->tdd_table.tdd_period.tl.tag = NFAPI_NR_CONFIG_TDD_PERIOD_TAG;
|
||||||
|
cfg->num_tlv++;
|
||||||
|
cfg->tdd_table.tdd_period.value = get_tdd_period_idx(scc->tdd_UL_DL_ConfigurationCommon);
|
||||||
|
LOG_D(NR_MAC, "Setting TDD configuration period to %d\n", cfg->tdd_table.tdd_period.value);
|
||||||
|
fs->numb_period_frame = get_nb_periods_per_frame(cfg->tdd_table.tdd_period.value);
|
||||||
|
fs->numb_slots_period = fs->numb_slots_frame / fs->numb_period_frame;
|
||||||
|
fs->is_tdd = true;
|
||||||
|
config_tdd_patterns(scc->tdd_UL_DL_ConfigurationCommon, fs);
|
||||||
|
set_tdd_config_nr(cfg, fs);
|
||||||
|
} else { // FDD
|
||||||
|
fs->is_tdd = false;
|
||||||
|
fs->numb_period_frame = 1;
|
||||||
|
fs->numb_slots_period = nr_slots_per_frame[mu];
|
||||||
|
}
|
||||||
|
AssertFatal(fs->numb_period_frame > 0, "Frame configuration cannot be configured!\n");
|
||||||
|
return fs->numb_period_frame;
|
||||||
|
}
|
||||||
|
|
||||||
static void config_common(gNB_MAC_INST *nrmac,
|
static void config_common(gNB_MAC_INST *nrmac,
|
||||||
const nr_mac_config_t *config,
|
const nr_mac_config_t *config,
|
||||||
NR_ServingCellConfigCommon_t *scc)
|
NR_ServingCellConfigCommon_t *scc)
|
||||||
@@ -317,10 +568,10 @@ static void config_common(gNB_MAC_INST *nrmac,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
struct NR_FrequencyInfoUL *frequencyInfoUL = scc->uplinkConfigCommon->frequencyInfoUL;
|
struct NR_FrequencyInfoUL *frequencyInfoUL = scc->uplinkConfigCommon->frequencyInfoUL;
|
||||||
|
int scs = frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
|
||||||
frequency_range = *frequencyInfoUL->frequencyBandList->list.array[0] > 256 ? FR2 : FR1;
|
frequency_range = *frequencyInfoUL->frequencyBandList->list.array[0] > 256 ? FR2 : FR1;
|
||||||
bw_index = get_supported_band_index(frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
|
bw_index =
|
||||||
frequency_range,
|
get_supported_band_index(scs, frequency_range, frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
|
||||||
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
|
|
||||||
cfg->carrier_config.uplink_bandwidth.value = get_supported_bw_mhz(frequency_range, bw_index);
|
cfg->carrier_config.uplink_bandwidth.value = get_supported_bw_mhz(frequency_range, bw_index);
|
||||||
cfg->carrier_config.uplink_bandwidth.tl.tag = NFAPI_NR_CONFIG_UPLINK_BANDWIDTH_TAG; // temporary
|
cfg->carrier_config.uplink_bandwidth.tl.tag = NFAPI_NR_CONFIG_UPLINK_BANDWIDTH_TAG; // temporary
|
||||||
cfg->num_tlv++;
|
cfg->num_tlv++;
|
||||||
@@ -339,7 +590,7 @@ static void config_common(gNB_MAC_INST *nrmac,
|
|||||||
cfg->num_tlv++;
|
cfg->num_tlv++;
|
||||||
|
|
||||||
for (int i = 0; i < 5; i++) {
|
for (int i = 0; i < 5; i++) {
|
||||||
if (i == frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing) {
|
if (i == scs) {
|
||||||
cfg->carrier_config.ul_grid_size[i].value = frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
|
cfg->carrier_config.ul_grid_size[i].value = frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
|
||||||
cfg->carrier_config.ul_k0[i].value = frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->offsetToCarrier;
|
cfg->carrier_config.ul_k0[i].value = frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->offsetToCarrier;
|
||||||
cfg->carrier_config.ul_grid_size[i].tl.tag = NFAPI_NR_CONFIG_UL_GRID_SIZE_TAG;
|
cfg->carrier_config.ul_grid_size[i].tl.tag = NFAPI_NR_CONFIG_UL_GRID_SIZE_TAG;
|
||||||
@@ -438,21 +689,15 @@ static void config_common(gNB_MAC_INST *nrmac,
|
|||||||
prach_fd_occasion->k1.value =
|
prach_fd_occasion->k1.value =
|
||||||
NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE)
|
NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE)
|
||||||
+ rach_ConfigCommon->rach_ConfigGeneric.msg1_FrequencyStart
|
+ rach_ConfigCommon->rach_ConfigGeneric.msg1_FrequencyStart
|
||||||
+ (get_N_RA_RB(cfg->prach_config.prach_sub_c_spacing.value,
|
+ (get_N_RA_RB(cfg->prach_config.prach_sub_c_spacing.value, scs) * i);
|
||||||
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing)
|
|
||||||
* i);
|
|
||||||
if (IS_SA_MODE(get_softmodem_params())) {
|
if (IS_SA_MODE(get_softmodem_params())) {
|
||||||
prach_fd_occasion->k1.value =
|
prach_fd_occasion->k1.value =
|
||||||
NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE)
|
NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE)
|
||||||
+ rach_ConfigCommon->rach_ConfigGeneric.msg1_FrequencyStart
|
+ rach_ConfigCommon->rach_ConfigGeneric.msg1_FrequencyStart
|
||||||
+ (get_N_RA_RB(cfg->prach_config.prach_sub_c_spacing.value,
|
+ (get_N_RA_RB(cfg->prach_config.prach_sub_c_spacing.value, scs) * i);
|
||||||
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing)
|
|
||||||
* i);
|
|
||||||
} else {
|
} else {
|
||||||
prach_fd_occasion->k1.value = rach_ConfigCommon->rach_ConfigGeneric.msg1_FrequencyStart
|
prach_fd_occasion->k1.value = rach_ConfigCommon->rach_ConfigGeneric.msg1_FrequencyStart
|
||||||
+ (get_N_RA_RB(cfg->prach_config.prach_sub_c_spacing.value,
|
+ (get_N_RA_RB(cfg->prach_config.prach_sub_c_spacing.value, scs) * i);
|
||||||
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing)
|
|
||||||
* i);
|
|
||||||
}
|
}
|
||||||
prach_fd_occasion->k1.tl.tag = NFAPI_NR_CONFIG_K1_TAG;
|
prach_fd_occasion->k1.tl.tag = NFAPI_NR_CONFIG_K1_TAG;
|
||||||
cfg->num_tlv++;
|
cfg->num_tlv++;
|
||||||
@@ -572,28 +817,9 @@ static void config_common(gNB_MAC_INST *nrmac,
|
|||||||
cfg->num_tlv++;
|
cfg->num_tlv++;
|
||||||
cfg->num_tlv++;
|
cfg->num_tlv++;
|
||||||
|
|
||||||
// TDD Table Configuration
|
// Frame structure configuration
|
||||||
if (cfg->cell_config.frame_duplex_type.value == TDD) {
|
uint8_t mu = frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
|
||||||
cfg->tdd_table.tdd_period.tl.tag = NFAPI_NR_CONFIG_TDD_PERIOD_TAG;
|
config_frame_structure(mu, scc, cfg, &nrmac->frame_structure);
|
||||||
cfg->num_tlv++;
|
|
||||||
if (scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1 == NULL) {
|
|
||||||
cfg->tdd_table.tdd_period.value = scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity;
|
|
||||||
} else {
|
|
||||||
AssertFatal(scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530 != NULL,
|
|
||||||
"In %s: scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530 is null\n",
|
|
||||||
__FUNCTION__);
|
|
||||||
cfg->tdd_table.tdd_period.value = *scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530;
|
|
||||||
}
|
|
||||||
LOG_D(NR_MAC, "Setting TDD configuration period to %d\n", cfg->tdd_table.tdd_period.value);
|
|
||||||
int periods_per_frame = set_tdd_config_nr(cfg,
|
|
||||||
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
|
|
||||||
scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots,
|
|
||||||
scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSymbols,
|
|
||||||
scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots,
|
|
||||||
scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols);
|
|
||||||
|
|
||||||
AssertFatal(periods_per_frame > 0, "TDD configuration cannot be configured\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
int nb_tx = config->nb_bfw[0]; // number of tx antennas
|
int nb_tx = config->nb_bfw[0]; // number of tx antennas
|
||||||
int nb_beams = config->nb_bfw[1]; // number of beams
|
int nb_beams = config->nb_bfw[1]; // number of beams
|
||||||
@@ -691,31 +917,6 @@ void nr_mac_config_scc(gNB_MAC_INST *nrmac, NR_ServingCellConfigCommon_t *scc, c
|
|||||||
|
|
||||||
find_SSB_and_RO_available(nrmac);
|
find_SSB_and_RO_available(nrmac);
|
||||||
|
|
||||||
const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
|
|
||||||
|
|
||||||
int nr_slots_period = n;
|
|
||||||
int nr_dl_slots = n;
|
|
||||||
int nr_ulstart_slot = 0;
|
|
||||||
if (tdd) {
|
|
||||||
nr_dl_slots = tdd->nrofDownlinkSlots + (tdd->nrofDownlinkSymbols != 0);
|
|
||||||
nr_ulstart_slot = get_first_ul_slot(tdd->nrofDownlinkSlots, tdd->nrofDownlinkSymbols, tdd->nrofUplinkSymbols);
|
|
||||||
nr_slots_period /= get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity);
|
|
||||||
} else {
|
|
||||||
// if TDD configuration is not present and the band is not FDD, it means it is a dynamic TDD configuration
|
|
||||||
AssertFatal(nrmac->common_channels[0].frame_type == FDD,"Dynamic TDD not handled yet\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int slot = 0; slot < n; ++slot) {
|
|
||||||
nrmac->dlsch_slot_bitmap[slot / 64] |= (uint64_t)((slot % nr_slots_period) < nr_dl_slots) << (slot % 64);
|
|
||||||
nrmac->ulsch_slot_bitmap[slot / 64] |= (uint64_t)((slot % nr_slots_period) >= nr_ulstart_slot) << (slot % 64);
|
|
||||||
|
|
||||||
LOG_D(NR_MAC,
|
|
||||||
"slot %d DL %d UL %d\n",
|
|
||||||
slot,
|
|
||||||
(nrmac->dlsch_slot_bitmap[slot / 64] & ((uint64_t)1 << (slot % 64))) != 0,
|
|
||||||
(nrmac->ulsch_slot_bitmap[slot / 64] & ((uint64_t)1 << (slot % 64))) != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
NR_COMMON_channels_t *cc = &nrmac->common_channels[0];
|
NR_COMMON_channels_t *cc = &nrmac->common_channels[0];
|
||||||
NR_SCHED_LOCK(&nrmac->sched_lock);
|
NR_SCHED_LOCK(&nrmac->sched_lock);
|
||||||
for (int n = 0; n < NR_NB_RA_PROC_MAX; n++) {
|
for (int n = 0; n < NR_NB_RA_PROC_MAX; n++) {
|
||||||
|
|||||||
@@ -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 */
|
/* 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->SFN = msgA_pusch_frame;
|
||||||
UL_tti_req->Slot = msgA_pusch_slot;
|
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",
|
"Slot %d is not an Uplink slot, invalid msgA_PUSCH_TimeDomainOffset_r16 %ld\n",
|
||||||
msgA_pusch_slot,
|
msgA_pusch_slot,
|
||||||
msgA_PUSCH_Resource->msgA_PUSCH_TimeDomainOffset_r16);
|
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_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];
|
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;
|
const NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &rach_ConfigCommon->rach_ConfigGeneric;
|
||||||
uint8_t config_index = rach_ConfigGeneric->prach_ConfigurationIndex;
|
uint8_t config_index = rach_ConfigGeneric->prach_ConfigurationIndex;
|
||||||
uint8_t N_dur, N_t_slot, start_symbol = 0, N_RA_slot;
|
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_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 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];
|
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);
|
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)
|
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->ra_state = nrRA_WAIT_Msg3;
|
||||||
ra->Msg3_frame = sched_frame;
|
ra->Msg3_frame = sched_frame;
|
||||||
ra->Msg3_slot = sched_slot;
|
ra->Msg3_slot = sched_slot;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool get_feasible_msg3_tda(frame_type_t frame_type,
|
static bool get_feasible_msg3_tda(const NR_ServingCellConfigCommon_t *scc,
|
||||||
const NR_ServingCellConfigCommon_t *scc,
|
|
||||||
int mu_delta,
|
int mu_delta,
|
||||||
uint64_t ulsch_slot_bitmap[3],
|
|
||||||
const NR_PUSCH_TimeDomainResourceAllocationList_t *tda_list,
|
const NR_PUSCH_TimeDomainResourceAllocationList_t *tda_list,
|
||||||
int slots_per_frame,
|
|
||||||
int frame,
|
int frame,
|
||||||
int slot,
|
int slot,
|
||||||
NR_RA_t *ra,
|
NR_RA_t *ra,
|
||||||
NR_beam_info_t *beam_info,
|
NR_beam_info_t *beam_info,
|
||||||
const NR_TDD_UL_DL_Pattern_t *tdd)
|
const frame_structure_t *fs)
|
||||||
{
|
{
|
||||||
DevAssert(tda_list != NULL);
|
DevAssert(tda_list != NULL);
|
||||||
|
|
||||||
const int NTN_gNB_Koffset = get_NTN_Koffset(scc);
|
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++) {
|
for (int i = 0; i < tda_list->list.count; i++) {
|
||||||
// check if it is UL
|
// check if it is UL
|
||||||
long k2 = *tda_list->list.array[i]->k2 + NTN_gNB_Koffset;
|
long k2 = *tda_list->list.array[i]->k2 + NTN_gNB_Koffset;
|
||||||
int abs_slot = slot + k2 + mu_delta;
|
int abs_slot = slot + k2 + mu_delta;
|
||||||
int temp_frame = (frame + (abs_slot / slots_per_frame)) & 1023;
|
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
|
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;
|
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
|
// check if enough symbols in case of mixed slot
|
||||||
bool is_mixed = false;
|
bool is_mixed = is_mixed_slot(s, fs);
|
||||||
if (frame_type == TDD) {
|
|
||||||
bool has_mixed = tdd->nrofUplinkSymbols != 0 || tdd->nrofDownlinkSymbols != 0;
|
|
||||||
is_mixed = has_mixed && ((temp_slot % tdd_period_slot) == tdd->nrofDownlinkSlots);
|
|
||||||
}
|
|
||||||
// if the mixed slot has not enough symbols, skip
|
// 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;
|
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;
|
long startSymbolAndLength = tda_list->list.array[i]->startSymbolAndLength;
|
||||||
int start, nr;
|
int start, nr;
|
||||||
SLIV2SL(startSymbolAndLength, &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];
|
gNB_MAC_INST *nr_mac = RC.nrmac[module_idP];
|
||||||
|
|
||||||
// no DL -> cannot send Msg2
|
// 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1413,18 +1410,14 @@ static void nr_generate_Msg2(module_id_t module_idP,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
const NR_UE_UL_BWP_t *ul_bwp = &ra->UL_BWP;
|
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(scc,
|
||||||
bool ret = get_feasible_msg3_tda(cc->frame_type,
|
|
||||||
scc,
|
|
||||||
DELTA[ul_bwp->scs],
|
DELTA[ul_bwp->scs],
|
||||||
nr_mac->ulsch_slot_bitmap,
|
|
||||||
ul_bwp->tdaList_Common,
|
ul_bwp->tdaList_Common,
|
||||||
nr_slots_per_frame[ul_bwp->scs],
|
|
||||||
frameP,
|
frameP,
|
||||||
slotP,
|
slotP,
|
||||||
ra,
|
ra,
|
||||||
&nr_mac->beam_info,
|
&nr_mac->beam_info,
|
||||||
tdd);
|
&nr_mac->frame_structure);
|
||||||
if (!ret || ra->Msg3_tda_id > 15) {
|
if (!ret || ra->Msg3_tda_id > 15) {
|
||||||
LOG_D(NR_MAC, "UE RNTI %04x %d.%d: infeasible Msg3 TDA\n", ra->rnti, frameP, slotP);
|
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);
|
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");
|
AssertFatal(coreset, "Coreset cannot be null for RA-Msg2\n");
|
||||||
const int coresetid = coreset->controlResourceSetId;
|
const int coresetid = coreset->controlResourceSetId;
|
||||||
// Calculate number of symbols
|
// 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;
|
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,
|
NR_tda_info_t tda_info = get_dl_tda_info(dl_bwp,
|
||||||
ss->searchSpaceType->present,
|
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_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id];
|
||||||
NR_UE_DL_BWP_t *dl_bwp = &ra->DL_BWP;
|
NR_UE_DL_BWP_t *dl_bwp = &ra->DL_BWP;
|
||||||
|
|
||||||
// if it is a DL slot, if the RA is in MSG4 state
|
// 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 (is_dl_slot(slotP, &nr_mac->frame_structure)) {
|
||||||
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
|
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
|
||||||
NR_SearchSpace_t *ss = ra->ra_ss;
|
NR_SearchSpace_t *ss = ra->ra_ss;
|
||||||
const char *ra_type_str = ra->ra_type == RA_2_STEP ? "MsgB" : "Msg4";
|
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;
|
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;
|
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,
|
NR_tda_info_t msg4_tda = get_dl_tda_info(dl_bwp,
|
||||||
ss->searchSpaceType->present,
|
ss->searchSpaceType->present,
|
||||||
|
|||||||
@@ -52,20 +52,22 @@
|
|||||||
#define WORD 32
|
#define WORD 32
|
||||||
//#define SIZE_OF_POINTER sizeof (void *)
|
//#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 */
|
/* 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;
|
const frame_structure_t *fs = &nrmac->frame_structure;
|
||||||
AssertFatal(tdd || nrmac->common_channels->frame_type == FDD, "Dynamic TDD not handled yet\n");
|
|
||||||
|
|
||||||
// Use special TDA in case of CSI-RS
|
// Use special TDA in case of CSI-RS
|
||||||
if(nrmac->UE_info.sched_csirs > 0)
|
if (nrmac->UE_info.sched_csirs > 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (tdd && tdd->nrofDownlinkSymbols > 1) { // if there is a mixed slot where we can transmit DL
|
if (fs->is_tdd) {
|
||||||
const int nr_slots_period = tdd->nrofDownlinkSlots + tdd->nrofUplinkSlots + 1;
|
int s = get_slot_idx_in_period(slot, fs);
|
||||||
if ((slot % nr_slots_period) == tdd->nrofDownlinkSlots)
|
// 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 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0; // if FDD or not mixed slot in TDD, for now use default TDA
|
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;
|
int pm_index = (curInfo->nrOfLayers < retInfo->nrOfLayers) ? curInfo->pm_index : retInfo->pm_index;
|
||||||
|
|
||||||
const int coresetid = sched_ctrl->coreset->controlResourceSetId;
|
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");
|
AssertFatal(tda >= 0,"Unable to find PDSCH time domain allocation in list\n");
|
||||||
|
|
||||||
/* Check first whether the old TDA can be reused
|
/* 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;
|
sched_pdsch->dl_harq_pid = sched_ctrl->available_dl_harq.head;
|
||||||
|
|
||||||
/* MCS has been set above */
|
/* 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");
|
AssertFatal(sched_pdsch->time_domain_allocation>=0,"Unable to find PDSCH time domain allocation in list\n");
|
||||||
|
|
||||||
const int coresetid = sched_ctrl->coreset->controlResourceSetId;
|
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,
|
AssertFatal(pthread_mutex_trylock(&gNB_mac->sched_lock) == EBUSY,
|
||||||
"this function should be called with the scheduler mutex locked\n");
|
"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;
|
return;
|
||||||
|
|
||||||
/* PREPROCESSOR */
|
/* PREPROCESSOR */
|
||||||
|
|||||||
@@ -40,6 +40,14 @@
|
|||||||
// #define UL_HARQ_PRINT
|
// #define UL_HARQ_PRINT
|
||||||
// #define ENABLE_MAC_PAYLOAD_DEBUG 1
|
// #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_mcs = 9;
|
||||||
uint32_t target_dl_Nl = 1;
|
uint32_t target_dl_Nl = 1;
|
||||||
uint32_t target_dl_bw = 50;
|
uint32_t target_dl_bw = 50;
|
||||||
@@ -64,7 +72,7 @@ void nr_preprocessor_phytest(module_id_t module_id,
|
|||||||
return;
|
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,
|
NR_tda_info_t tda_info = get_dl_tda_info(dl_bwp,
|
||||||
sched_ctrl->search_space->searchSpaceType->present,
|
sched_ctrl->search_space->searchSpaceType->present,
|
||||||
tda,
|
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->coreset->controlResourceSetId,
|
||||||
sched_ctrl->search_space->searchSpaceType->present,
|
sched_ctrl->search_space->searchSpaceType->present,
|
||||||
TYPE_C_RNTI_);
|
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)
|
if (temp_tda < 0)
|
||||||
return false;
|
return false;
|
||||||
AssertFatal(temp_tda < tdaList->list.count,
|
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);
|
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_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 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)
|
if (tda < 0)
|
||||||
return false;
|
return false;
|
||||||
AssertFatal(tda < tdaList->list.count,
|
AssertFatal(tda < tdaList->list.count,
|
||||||
|
|||||||
@@ -2160,6 +2160,31 @@ int get_ulbw_tbslbrm(int scc_bwpsize, const NR_ServingCellConfig_t *servingCellC
|
|||||||
return bw;
|
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
|
// main function to configure parameters of current BWP
|
||||||
void configure_UE_BWP(gNB_MAC_INST *nr_mac,
|
void configure_UE_BWP(gNB_MAC_INST *nr_mac,
|
||||||
NR_ServingCellConfigCommon_t *scc,
|
NR_ServingCellConfigCommon_t *scc,
|
||||||
@@ -2405,7 +2430,7 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac,
|
|||||||
NR_UL_DCI_FORMAT_0_0;
|
NR_UL_DCI_FORMAT_0_0;
|
||||||
|
|
||||||
set_max_fb_time(UL_BWP, DL_BWP);
|
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) {
|
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);
|
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)
|
void free_sched_pucch_list(NR_UE_sched_ctrl_t *sched_ctrl)
|
||||||
{
|
{
|
||||||
free(sched_ctrl->sched_pucch);
|
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
|
-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
|
// 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
|
// 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 = get_ul_slots_per_period(fs);
|
||||||
const int n_ul_slots_period = tdd ? tdd->nrofUplinkSlots + (tdd->nrofUplinkSymbols > 0 ? 1 : 0) : n_slots_frame;
|
const int n_ul_slots_frame = get_ul_slots_per_frame(fs);
|
||||||
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;
|
|
||||||
// (frame * n_ul_slots_frame) adds up the number of UL slots in the previous frames
|
// (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;
|
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
|
// ((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
|
// ((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
|
// 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;
|
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)
|
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() */
|
/* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */
|
||||||
NR_SCHED_ENSURE_LOCKED(&nrmac->sched_lock);
|
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;
|
return;
|
||||||
|
|
||||||
UE_iterator(nrmac->UE_info.list, UE) {
|
UE_iterator(nrmac->UE_info.list, UE) {
|
||||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||||
NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP;
|
const int pucch_index = get_pucch_index(frameP, slotP, &nrmac->frame_structure, sched_ctrl->sched_pucch_size);
|
||||||
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);
|
|
||||||
NR_sched_pucch_t *curr_pucch = &UE->UE_sched_ctrl.sched_pucch[pucch_index];
|
NR_sched_pucch_t *curr_pucch = &UE->UE_sched_ctrl.sched_pucch[pucch_index];
|
||||||
if (!curr_pucch->active)
|
if (!curr_pucch->active)
|
||||||
continue;
|
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)
|
if ((sched_frame * n_slots_frame + sched_slot - offset) % period != 0)
|
||||||
continue;
|
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);
|
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
|
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,
|
AssertFatal(res_index < n,
|
||||||
"CSI pucch resource %ld not found among PUCCH resources\n", pucchcsires->pucch_Resource);
|
"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;
|
const int pucch_index = get_pucch_index(sched_frame, sched_slot, &nrmac->frame_structure, sched_ctrl->sched_pucch_size);
|
||||||
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);
|
|
||||||
NR_sched_pucch_t *curr_pucch = &sched_ctrl->sched_pucch[pucch_index];
|
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");
|
AssertFatal(curr_pucch->active == false, "CSI structure is scheduled in advance. It should be free!\n");
|
||||||
curr_pucch->r_pucch = -1;
|
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 int minfbtime = mac->radio_config.minRXTXTIME + NTN_gNB_Koffset;
|
||||||
const NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP;
|
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 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;
|
const frame_structure_t *fs = &mac->frame_structure;
|
||||||
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;
|
|
||||||
|
|
||||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||||
NR_PUCCH_Config_t *pucch_Config = ul_bwp->pucch_Config;
|
NR_PUCCH_Config_t *pucch_Config = ul_bwp->pucch_Config;
|
||||||
@@ -1022,11 +1024,14 @@ int nr_acknack_scheduling(gNB_MAC_INST *mac,
|
|||||||
continue;
|
continue;
|
||||||
const int pucch_slot = (slot + pdsch_to_harq_feedback[f] + NTN_gNB_Koffset) % n_slots_frame;
|
const int pucch_slot = (slot + pdsch_to_harq_feedback[f] + NTN_gNB_Koffset) % n_slots_frame;
|
||||||
// check if the slot is UL
|
// check if the slot is UL
|
||||||
if(pucch_slot%nr_slots_period < first_ul_slot_period)
|
if (fs->is_tdd) {
|
||||||
continue;
|
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;
|
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
|
// 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];
|
NR_sched_pucch_t *curr_pucch = &sched_ctrl->sched_pucch[pucch_index];
|
||||||
if (curr_pucch->active &&
|
if (curr_pucch->active &&
|
||||||
curr_pucch->frame == pucch_frame &&
|
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() */
|
/* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */
|
||||||
NR_SCHED_ENSURE_LOCKED(&nrmac->sched_lock);
|
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;
|
return;
|
||||||
const int CC_id = 0;
|
const int CC_id = 0;
|
||||||
UE_iterator(nrmac->UE_info.list, UE) {
|
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");
|
AssertFatal(idx > -1, "SR resource not found among PUCCH resources");
|
||||||
|
|
||||||
const NR_ServingCellConfigCommon_t *scc = nrmac->common_channels[CC_id].ServingCellConfigCommon;
|
const int pucch_index = get_pucch_index(SFN, slot, &nrmac->frame_structure, sched_ctrl->sched_pucch_size);
|
||||||
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);
|
|
||||||
NR_sched_pucch_t *curr_pucch = &sched_ctrl->sched_pucch[pucch_index];
|
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)
|
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
|
//#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 */
|
/* we assume that this function is mutex-protected from outside */
|
||||||
NR_SCHED_ENSURE_LOCKED(&nrmac->sched_lock);
|
NR_SCHED_ENSURE_LOCKED(&nrmac->sched_lock);
|
||||||
|
|
||||||
/* there is a mixed slot only when in TDD */
|
/* 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;
|
frame_structure_t *fs = &nrmac->frame_structure;
|
||||||
AssertFatal(tdd || nrmac->common_channels->frame_type == FDD, "Dynamic TDD not handled yet\n");
|
|
||||||
|
|
||||||
if (tdd && tdd->nrofUplinkSymbols > 1) { // if there is uplink symbols in mixed slot
|
if (fs->is_tdd) {
|
||||||
const int nr_slots_period = tdd->nrofDownlinkSlots + tdd->nrofUplinkSlots + 1;
|
// if there is uplink symbols in mixed slot
|
||||||
if ((slot % nr_slots_period) == tdd->nrofDownlinkSlots)
|
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;
|
return 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Avoid slots with the SRS
|
// Avoid slots with the SRS
|
||||||
@@ -1519,25 +1521,21 @@ long get_K2(NR_PUSCH_TimeDomainResourceAllocationList_t *tdaList,
|
|||||||
return 3 + NTN_gNB_Koffset;
|
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 int now = frame * n + slot;
|
||||||
|
|
||||||
const NR_UE_sched_ctrl_t *sched_ctrl =&UE->UE_sched_ctrl;
|
const NR_UE_sched_ctrl_t *sched_ctrl =&UE->UE_sched_ctrl;
|
||||||
|
/**
|
||||||
const NR_TDD_UL_DL_Pattern_t *tdd =
|
* Force the default transmission in a full slot as early
|
||||||
scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
|
* as possible in the UL portion of TDD period (last_ul_slot) */
|
||||||
int num_slots_per_period;
|
int num_slots_per_period = fs->numb_slots_period;
|
||||||
int last_ul_slot;
|
int last_ul_slot = fs->is_tdd ? get_first_ul_slot(fs, false) : sched_ctrl->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;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int last_ul_sched = sched_ctrl->last_ul_frame * n + 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);
|
const int diff = (now - last_ul_sched + 1024 * n) % (1024 * n);
|
||||||
/* UE is to be scheduled if
|
/* 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);
|
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) {
|
if (sched_pusch->ul_harq_pid >= 0) {
|
||||||
/* Allocate retransmission*/
|
/* 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,
|
bool r = allocate_ul_retransmission(nrmac,
|
||||||
frame,
|
frame,
|
||||||
slot,
|
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);
|
const int B = max(0, sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes);
|
||||||
/* preprocessor computed sched_frame/sched_slot */
|
/* 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");
|
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)) {
|
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->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_pusch->tda_info = get_ul_tda_info(current_BWP,
|
||||||
sched_ctrl->coreset->controlResourceSetId,
|
sched_ctrl->coreset->controlResourceSetId,
|
||||||
sched_ctrl->search_space->searchSpaceType->present,
|
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->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_pusch->tda_info = get_ul_tda_info(current_BWP,
|
||||||
sched_ctrl->coreset->controlResourceSetId,
|
sched_ctrl->coreset->controlResourceSetId,
|
||||||
sched_ctrl->search_space->searchSpaceType->present,
|
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 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_frame = (frame + (slot + K2) / slots_frame) % MAX_FRAME_NUMBER;
|
||||||
const int sched_slot = (slot + K2) % slots_frame;
|
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;
|
return false;
|
||||||
|
|
||||||
int num_beams = nr_mac->beam_info.beam_allocation ? nr_mac->beam_info.beams_per_period : 1;
|
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,
|
/* 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 */
|
* 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);
|
LOG_D(NR_MAC, "Current slot %d is NOT DL slot, cannot schedule DCI0 for UL data\n", slot);
|
||||||
return;
|
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);
|
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_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,
|
void mac_top_init_gNB(ngran_node_t node_type,
|
||||||
NR_ServingCellConfigCommon_t *scc,
|
NR_ServingCellConfigCommon_t *scc,
|
||||||
NR_ServingCellConfig_t *scd,
|
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);
|
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.
|
/* \brief Function to indicate a received SDU on ULSCH.
|
||||||
@param Mod_id Instance ID of gNB
|
@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);
|
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);
|
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_dl_tda(const gNB_MAC_INST *nrmac, int slot);
|
||||||
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);
|
||||||
|
|
||||||
int get_cce_index(const gNB_MAC_INST *nrmac,
|
int get_cce_index(const gNB_MAC_INST *nrmac,
|
||||||
const int CC_id,
|
const int CC_id,
|
||||||
|
|||||||
@@ -905,13 +905,10 @@ typedef struct gNB_MAC_INST_s {
|
|||||||
|
|
||||||
NR_beam_info_t beam_info;
|
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
|
/// maximum number of slots before a UE will be scheduled ULSCH automatically
|
||||||
uint32_t ulsch_max_frame_inactivity;
|
uint32_t ulsch_max_frame_inactivity;
|
||||||
|
/// instance of the frame structure configuration
|
||||||
|
frame_structure_t frame_structure;
|
||||||
|
|
||||||
/// DL preprocessor for differentiated scheduling
|
/// DL preprocessor for differentiated scheduling
|
||||||
nr_pp_impl_dl pre_processor_dl;
|
nr_pp_impl_dl pre_processor_dl;
|
||||||
|
|||||||
+163
-75
@@ -49,7 +49,9 @@
|
|||||||
#include "constr_TYPE.h"
|
#include "constr_TYPE.h"
|
||||||
#include "executables/softmodem-common.h"
|
#include "executables/softmodem-common.h"
|
||||||
#include "oai_asn1.h"
|
#include "oai_asn1.h"
|
||||||
|
#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
|
||||||
#include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
|
#include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
|
||||||
|
#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
|
||||||
#include "openair3/UTILS/conversions.h"
|
#include "openair3/UTILS/conversions.h"
|
||||||
#include "uper_decoder.h"
|
#include "uper_decoder.h"
|
||||||
#include "uper_encoder.h"
|
#include "uper_encoder.h"
|
||||||
@@ -312,9 +314,13 @@ static uint64_t get_ssb_bitmap(const NR_ServingCellConfigCommon_t *scc)
|
|||||||
return bitmap;
|
return bitmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int set_ideal_period(const int n_slots_period, const int n_ul_slots_period)
|
static int set_ideal_period(bool is_csi)
|
||||||
{
|
{
|
||||||
return MAX_MOBILES_PER_GNB * 2 * n_slots_period / n_ul_slots_period; // 2 reports per UE (RSRP and RI-PMI-CQI)
|
const frame_structure_t *fs = &RC.nrmac[0]->frame_structure;
|
||||||
|
const int nb_slots_per_period = fs->numb_slots_period;
|
||||||
|
const int n_ul_slots_per_period = get_ul_slots_per_period(fs); // full UL + mixed with UL symbols
|
||||||
|
// 2 reports per UE (RSRP and RI-PMI-CQI)
|
||||||
|
return is_csi ? MAX_MOBILES_PER_GNB * 2 * nb_slots_per_period / n_ul_slots_per_period : nb_slots_per_period * MAX_MOBILES_PER_GNB;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_csirs_periodicity(NR_NZP_CSI_RS_Resource_t *nzpcsi0,
|
static void set_csirs_periodicity(NR_NZP_CSI_RS_Resource_t *nzpcsi0,
|
||||||
@@ -389,16 +395,6 @@ static void config_csirs(const NR_ServingCellConfigCommon_t *servingcellconfigco
|
|||||||
nzpcsirs0->aperiodicTriggeringOffset = NULL;
|
nzpcsirs0->aperiodicTriggeringOffset = NULL;
|
||||||
nzpcsirs0->trs_Info = NULL;
|
nzpcsirs0->trs_Info = NULL;
|
||||||
asn1cSeqAdd(&csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list,nzpcsirs0);
|
asn1cSeqAdd(&csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list,nzpcsirs0);
|
||||||
|
|
||||||
const NR_TDD_UL_DL_Pattern_t *tdd = servingcellconfigcommon->tdd_UL_DL_ConfigurationCommon ?
|
|
||||||
&servingcellconfigcommon->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
|
|
||||||
|
|
||||||
const int n_slots_frame = slotsperframe[*servingcellconfigcommon->ssbSubcarrierSpacing];
|
|
||||||
const int nb_slots_per_period = tdd ? n_slots_frame/get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity): n_slots_frame;
|
|
||||||
const int nb_dl_slots_period = tdd ? tdd->nrofDownlinkSlots : n_slots_frame;
|
|
||||||
const int n_ul_slots_period = tdd ? (tdd->nrofUplinkSlots + (tdd->nrofUplinkSymbols > 0)) : n_slots_frame;
|
|
||||||
const int ideal_period = set_ideal_period(nb_slots_per_period, n_ul_slots_period); // same periodicity as CSI measurement report
|
|
||||||
|
|
||||||
if(!csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList)
|
if(!csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList)
|
||||||
csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList = calloc(1,sizeof(*csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList));
|
csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList = calloc(1,sizeof(*csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList));
|
||||||
NR_NZP_CSI_RS_Resource_t *nzpcsi0 = calloc(1,sizeof(*nzpcsi0));
|
NR_NZP_CSI_RS_Resource_t *nzpcsi0 = calloc(1,sizeof(*nzpcsi0));
|
||||||
@@ -447,7 +443,12 @@ static void config_csirs(const NR_ServingCellConfigCommon_t *servingcellconfigco
|
|||||||
nzpcsi0->powerControlOffsetSS = calloc(1,sizeof(*nzpcsi0->powerControlOffsetSS));
|
nzpcsi0->powerControlOffsetSS = calloc(1,sizeof(*nzpcsi0->powerControlOffsetSS));
|
||||||
*nzpcsi0->powerControlOffsetSS = NR_NZP_CSI_RS_Resource__powerControlOffsetSS_db0;
|
*nzpcsi0->powerControlOffsetSS = NR_NZP_CSI_RS_Resource__powerControlOffsetSS_db0;
|
||||||
nzpcsi0->scramblingID = *servingcellconfigcommon->physCellId;
|
nzpcsi0->scramblingID = *servingcellconfigcommon->physCellId;
|
||||||
set_csirs_periodicity(nzpcsi0, id, ideal_period, nb_slots_per_period, nb_dl_slots_period);
|
|
||||||
|
const int ideal_period = set_ideal_period(true); // same periodicity as CSI measurement report
|
||||||
|
const frame_structure_t *fs = &(RC.nrmac[0]->frame_structure);
|
||||||
|
const int nb_dl_slots_period = get_full_dl_slots_per_period(fs); // full DL slots
|
||||||
|
set_csirs_periodicity(nzpcsi0, id, ideal_period, fs->numb_slots_period, nb_dl_slots_period);
|
||||||
|
|
||||||
nzpcsi0->qcl_InfoPeriodicCSI_RS = calloc(1,sizeof(*nzpcsi0->qcl_InfoPeriodicCSI_RS));
|
nzpcsi0->qcl_InfoPeriodicCSI_RS = calloc(1,sizeof(*nzpcsi0->qcl_InfoPeriodicCSI_RS));
|
||||||
*nzpcsi0->qcl_InfoPeriodicCSI_RS = 0;
|
*nzpcsi0->qcl_InfoPeriodicCSI_RS = 0;
|
||||||
asn1cSeqAdd(&csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList->list,nzpcsi0);
|
asn1cSeqAdd(&csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList->list,nzpcsi0);
|
||||||
@@ -628,15 +629,12 @@ long rrc_get_max_nr_csrs(const int max_rbs, const long b_SRS) {
|
|||||||
static struct NR_SRS_Resource__resourceType__periodic *configure_periodic_srs(const NR_ServingCellConfigCommon_t *scc,
|
static struct NR_SRS_Resource__resourceType__periodic *configure_periodic_srs(const NR_ServingCellConfigCommon_t *scc,
|
||||||
const int uid)
|
const int uid)
|
||||||
{
|
{
|
||||||
|
frame_structure_t *fs = &RC.nrmac[0]->frame_structure;
|
||||||
|
int offset = get_ul_slot_offset(fs, uid, false); // only full UL slots for SRS
|
||||||
|
|
||||||
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 = slotsperframe[*scc->ssbSubcarrierSpacing];
|
|
||||||
const int ul_slots_period = tdd ? tdd->nrofUplinkSlots : n_slots_frame;
|
|
||||||
const int n_slots_period = tdd ? n_slots_frame/get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity) : n_slots_frame;
|
|
||||||
const int first_full_ul_slot = n_slots_period - ul_slots_period;
|
|
||||||
const int ideal_period = n_slots_period * MAX_MOBILES_PER_GNB;
|
|
||||||
const int offset = first_full_ul_slot + (uid % ul_slots_period) + (n_slots_period * (uid / ul_slots_period));
|
|
||||||
AssertFatal(offset < 2560, "Cannot allocate SRS configuration for uid %d, not enough resources\n", uid);
|
AssertFatal(offset < 2560, "Cannot allocate SRS configuration for uid %d, not enough resources\n", uid);
|
||||||
|
const int ideal_period = set_ideal_period(false);
|
||||||
|
|
||||||
struct NR_SRS_Resource__resourceType__periodic *periodic_srs = calloc(1,sizeof(*periodic_srs));
|
struct NR_SRS_Resource__resourceType__periodic *periodic_srs = calloc(1,sizeof(*periodic_srs));
|
||||||
if (ideal_period < 5) {
|
if (ideal_period < 5) {
|
||||||
periodic_srs->periodicityAndOffset_p.present = NR_SRS_PeriodicityAndOffset_PR_sl4;
|
periodic_srs->periodicityAndOffset_p.present = NR_SRS_PeriodicityAndOffset_PR_sl4;
|
||||||
@@ -907,7 +905,17 @@ void nr_rrc_config_dl_tda(struct NR_PDSCH_TimeDomainResourceAllocationList *pdsc
|
|||||||
if(frame_type==TDD) {
|
if(frame_type==TDD) {
|
||||||
// TDD
|
// TDD
|
||||||
if(tdd_UL_DL_ConfigurationCommon) {
|
if(tdd_UL_DL_ConfigurationCommon) {
|
||||||
int dl_symb = tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSymbols;
|
int dl_symb = 0;
|
||||||
|
if (tdd_UL_DL_ConfigurationCommon->pattern2 && tdd_UL_DL_ConfigurationCommon->pattern2->nrofDownlinkSymbols)
|
||||||
|
AssertFatal(tdd_UL_DL_ConfigurationCommon->pattern2->nrofDownlinkSymbols == tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSymbols,
|
||||||
|
"nrofDownlinkSymbols in pattern1 %ld and pattern2 %ld must be the same in current implementation\n",
|
||||||
|
tdd_UL_DL_ConfigurationCommon->pattern2->nrofDownlinkSymbols,
|
||||||
|
tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSymbols);
|
||||||
|
if (tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSymbols != 0) {
|
||||||
|
dl_symb = tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSymbols;
|
||||||
|
} else if (tdd_UL_DL_ConfigurationCommon->pattern2) {
|
||||||
|
dl_symb = tdd_UL_DL_ConfigurationCommon->pattern2->nrofDownlinkSymbols;
|
||||||
|
}
|
||||||
if(dl_symb > 1) {
|
if(dl_symb > 1) {
|
||||||
// mixed slot TDA with TDA index 2
|
// mixed slot TDA with TDA index 2
|
||||||
struct NR_PDSCH_TimeDomainResourceAllocation *timedomainresourceallocation2 = CALLOC(1,sizeof(NR_PDSCH_TimeDomainResourceAllocation_t));
|
struct NR_PDSCH_TimeDomainResourceAllocation *timedomainresourceallocation2 = CALLOC(1,sizeof(NR_PDSCH_TimeDomainResourceAllocation_t));
|
||||||
@@ -919,6 +927,94 @@ void nr_rrc_config_dl_tda(struct NR_PDSCH_TimeDomainResourceAllocationList *pdsc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const float tdd_ms_period_pattern[] = {0.5, 0.625, 1.0, 1.25, 2.0, 2.5, 5.0, 10.0};
|
||||||
|
const float tdd_ms_period_ext[] = {3.0, 4.0};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Retrieves the periodicity in milliseconds for the given TDD pattern
|
||||||
|
* depending on the presence of the extension
|
||||||
|
* @param pattern Pointer to the NR_TDD_UL_DL_Pattern_t pattern structure
|
||||||
|
* @return Periodicity value in milliseconds.
|
||||||
|
*/
|
||||||
|
static float get_tdd_periodicity(NR_TDD_UL_DL_Pattern_t *pattern) {
|
||||||
|
if (!pattern->ext1) {
|
||||||
|
LOG_D(NR_MAC, "Setting TDD configuration period to dl_UL_TransmissionPeriodicity %ld\n", pattern->dl_UL_TransmissionPeriodicity);
|
||||||
|
return tdd_ms_period_pattern[pattern->dl_UL_TransmissionPeriodicity];
|
||||||
|
} else {
|
||||||
|
DevAssert(pattern->ext1->dl_UL_TransmissionPeriodicity_v1530 != NULL);
|
||||||
|
LOG_D(NR_MAC,
|
||||||
|
"Setting TDD configuration period to dl_UL_TransmissionPeriodicity_v1530 %ld\n",
|
||||||
|
*pattern->ext1->dl_UL_TransmissionPeriodicity_v1530);
|
||||||
|
return tdd_ms_period_ext[*pattern->ext1->dl_UL_TransmissionPeriodicity_v1530];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Determines the TDD period index based on pattern periodicities
|
||||||
|
* @note Not applicabile to pattern extension
|
||||||
|
* @param tdd Pointer to the NR_TDD_UL_DL_ConfigCommon_t containing patterns
|
||||||
|
* @return Index of the TDD period in tdd_ms_period_pattern
|
||||||
|
*/
|
||||||
|
int get_tdd_period_idx(NR_TDD_UL_DL_ConfigCommon_t *tdd)
|
||||||
|
{
|
||||||
|
int tdd_period_idx = 0;
|
||||||
|
float pattern1_ms = get_tdd_periodicity(&tdd->pattern1);
|
||||||
|
float pattern2_ms = tdd->pattern2 ? get_tdd_periodicity(tdd->pattern2) : 0.0;
|
||||||
|
bool found_match = false;
|
||||||
|
// Find matching TDD period in the predefined list of periodicities
|
||||||
|
for (int i = 0; i < NFAPI_MAX_NUM_PERIODS; i++) {
|
||||||
|
if ((pattern1_ms + pattern2_ms) == tdd_ms_period_pattern[i]) {
|
||||||
|
tdd_period_idx = i;
|
||||||
|
LOG_I(NR_MAC,
|
||||||
|
"TDD period index = %d, based on the sum of dl_UL_TransmissionPeriodicity "
|
||||||
|
"from Pattern1 (%f ms) and Pattern2 (%f ms): Total = %f ms\n",
|
||||||
|
tdd_period_idx,
|
||||||
|
pattern1_ms,
|
||||||
|
pattern2_ms,
|
||||||
|
pattern1_ms + pattern2_ms);
|
||||||
|
found_match = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Assert if no match was found
|
||||||
|
AssertFatal(found_match, "The sum of pattern1_ms and pattern2_ms does not match any value in tdd_ms_period_pattern");
|
||||||
|
return tdd_period_idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct NR_PUSCH_TimeDomainResourceAllocation *set_TimeDomainResourceAllocation(const int k2, uint8_t index, int ul_symb)
|
||||||
|
{
|
||||||
|
struct NR_PUSCH_TimeDomainResourceAllocation *puschTdrAlloc = calloc_or_fail(1, sizeof(*puschTdrAlloc));
|
||||||
|
puschTdrAlloc->k2 = calloc_or_fail(1, sizeof(*puschTdrAlloc->k2));
|
||||||
|
*puschTdrAlloc->k2 = k2;
|
||||||
|
puschTdrAlloc->mappingType = NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB;
|
||||||
|
switch (index) {
|
||||||
|
case 0:
|
||||||
|
puschTdrAlloc->startSymbolAndLength = get_SLIV(0, 13);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
puschTdrAlloc->startSymbolAndLength = get_SLIV(0, 12);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
// UL TDA index 2 for mixed slot (TDD)
|
||||||
|
puschTdrAlloc->startSymbolAndLength =
|
||||||
|
get_SLIV(NR_NUMBER_OF_SYMBOLS_PER_SLOT - ul_symb, ul_symb - 1); // starting in fist ul symbol til the last but one
|
||||||
|
break;
|
||||||
|
case 3: {
|
||||||
|
// UL TDA index 3 for msg3 in the mixed slot (TDD)
|
||||||
|
int no_mix_slot = ul_symb < 3 ? 1 : 0; // we need at least 2 symbols for scheduling Msg3
|
||||||
|
*puschTdrAlloc->k2 += no_mix_slot;
|
||||||
|
if (no_mix_slot)
|
||||||
|
puschTdrAlloc->startSymbolAndLength = get_SLIV(0, 13); // full allocation if there is no mixed slot
|
||||||
|
else
|
||||||
|
puschTdrAlloc->startSymbolAndLength =
|
||||||
|
get_SLIV(NR_NUMBER_OF_SYMBOLS_PER_SLOT - ul_symb, ul_symb - 1); // starting in fist ul symbol til the last but one
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return puschTdrAlloc;
|
||||||
|
}
|
||||||
|
|
||||||
void nr_rrc_config_ul_tda(NR_ServingCellConfigCommon_t *scc, int min_fb_delay)
|
void nr_rrc_config_ul_tda(NR_ServingCellConfigCommon_t *scc, int min_fb_delay)
|
||||||
{
|
{
|
||||||
@@ -928,58 +1024,48 @@ void nr_rrc_config_ul_tda(NR_ServingCellConfigCommon_t *scc, int min_fb_delay)
|
|||||||
scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
|
scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
|
||||||
AssertFatal(tda->list.count == 0, "already have pusch_TimeDomainAllocationList members\n");
|
AssertFatal(tda->list.count == 0, "already have pusch_TimeDomainAllocationList members\n");
|
||||||
|
|
||||||
frame_type_t frame_type = get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing);
|
|
||||||
const int k2 = min_fb_delay;
|
const int k2 = min_fb_delay;
|
||||||
|
|
||||||
uint8_t DELTA[4]= {2,3,4,6}; // Delta parameter for Msg3
|
uint8_t DELTA[4]= {2,3,4,6}; // Delta parameter for Msg3
|
||||||
int mu = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing;
|
int mu = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing;
|
||||||
|
struct NR_SetupRelease_PUSCH_ConfigCommon *pusch_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon;
|
||||||
|
|
||||||
// UL TDA index 0 is basic slot configuration starting in symbol 0 til the last but one symbol
|
// UL TDA index 0 is basic slot configuration starting in symbol 0 til the last but one symbol
|
||||||
struct NR_PUSCH_TimeDomainResourceAllocation *pusch_timedomainresourceallocation = CALLOC(1,sizeof(struct NR_PUSCH_TimeDomainResourceAllocation));
|
asn1cSeqAdd(&pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list, set_TimeDomainResourceAllocation(k2, 0, 0));
|
||||||
pusch_timedomainresourceallocation->k2 = CALLOC(1,sizeof(long));
|
|
||||||
*pusch_timedomainresourceallocation->k2 = k2;
|
|
||||||
pusch_timedomainresourceallocation->mappingType = NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB;
|
|
||||||
pusch_timedomainresourceallocation->startSymbolAndLength = get_SLIV(0, 13);
|
|
||||||
asn1cSeqAdd(&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list,pusch_timedomainresourceallocation);
|
|
||||||
|
|
||||||
// UL TDA index 1 in case of SRS
|
// UL TDA index 1 in case of SRS
|
||||||
struct NR_PUSCH_TimeDomainResourceAllocation *pusch_timedomainresourceallocation1 = CALLOC(1,sizeof(struct NR_PUSCH_TimeDomainResourceAllocation));
|
asn1cSeqAdd(&pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list, set_TimeDomainResourceAllocation(k2, 1, 0));
|
||||||
pusch_timedomainresourceallocation1->k2 = CALLOC(1,sizeof(long));
|
|
||||||
*pusch_timedomainresourceallocation1->k2 = k2;
|
|
||||||
pusch_timedomainresourceallocation1->mappingType = NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB;
|
|
||||||
pusch_timedomainresourceallocation1->startSymbolAndLength = get_SLIV(0, 12);
|
|
||||||
asn1cSeqAdd(&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list,pusch_timedomainresourceallocation1);
|
|
||||||
|
|
||||||
if(frame_type==TDD) {
|
if (scc->tdd_UL_DL_ConfigurationCommon) {
|
||||||
if(scc->tdd_UL_DL_ConfigurationCommon) {
|
int ul_symb = 0;
|
||||||
int ul_symb = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols;
|
NR_TDD_UL_DL_Pattern_t *p1 = &scc->tdd_UL_DL_ConfigurationCommon->pattern1;
|
||||||
if (ul_symb>1) {
|
NR_TDD_UL_DL_Pattern_t *p2 = scc->tdd_UL_DL_ConfigurationCommon->pattern2;
|
||||||
// UL TDA index 2 for mixed slot (TDD)
|
if (p2 && p2->nrofUplinkSymbols)
|
||||||
pusch_timedomainresourceallocation = CALLOC(1,sizeof(struct NR_PUSCH_TimeDomainResourceAllocation));
|
AssertFatal(p2->nrofUplinkSymbols == p1->nrofUplinkSymbols,
|
||||||
pusch_timedomainresourceallocation->k2 = CALLOC(1,sizeof(long));
|
"nrofDownlinkSymbols in pattern1 %ld and pattern2 %ld must be the same in current implementation\n",
|
||||||
*pusch_timedomainresourceallocation->k2 = k2;
|
p1->nrofUplinkSymbols,
|
||||||
pusch_timedomainresourceallocation->mappingType = NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB;
|
p2->nrofUplinkSymbols);
|
||||||
pusch_timedomainresourceallocation->startSymbolAndLength = get_SLIV(14 - ul_symb, ul_symb - 1); // starting in fist ul symbol til the last but one
|
if (p1->nrofUplinkSymbols) {
|
||||||
asn1cSeqAdd(&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list,pusch_timedomainresourceallocation);
|
ul_symb = p1->nrofUplinkSymbols;
|
||||||
}
|
} else if (p2) {
|
||||||
// UL TDA index 3 for msg3 in the mixed slot (TDD)
|
ul_symb = p1->nrofUplinkSymbols;
|
||||||
int nb_periods_per_frame = get_nb_periods_per_frame(scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity);
|
|
||||||
int nb_slots_per_period = ((1 << mu) * 10) / nb_periods_per_frame;
|
|
||||||
struct NR_PUSCH_TimeDomainResourceAllocation *pusch_timedomainresourceallocation_msg3 = CALLOC(1,sizeof(struct NR_PUSCH_TimeDomainResourceAllocation));
|
|
||||||
pusch_timedomainresourceallocation_msg3->k2 = CALLOC(1,sizeof(long));
|
|
||||||
int no_mix_slot = ul_symb < 3 ? 1 : 0; // we need at least 2 symbols for scheduling Msg3
|
|
||||||
*pusch_timedomainresourceallocation_msg3->k2 = nb_slots_per_period - DELTA[mu] + no_mix_slot;
|
|
||||||
if(*pusch_timedomainresourceallocation_msg3->k2 < min_fb_delay)
|
|
||||||
*pusch_timedomainresourceallocation_msg3->k2 += nb_slots_per_period;
|
|
||||||
AssertFatal(*pusch_timedomainresourceallocation_msg3->k2 < 33,"Computed k2 for msg3 %ld is larger than the range allowed by RRC (0..32)\n",
|
|
||||||
*pusch_timedomainresourceallocation_msg3->k2);
|
|
||||||
pusch_timedomainresourceallocation_msg3->mappingType = NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB;
|
|
||||||
if(no_mix_slot)
|
|
||||||
pusch_timedomainresourceallocation_msg3->startSymbolAndLength = get_SLIV(0, 13); // full allocation if there is no mixed slot
|
|
||||||
else
|
|
||||||
pusch_timedomainresourceallocation_msg3->startSymbolAndLength = get_SLIV(14 - ul_symb, ul_symb - 1); // starting in fist ul symbol til the last but one
|
|
||||||
asn1cSeqAdd(&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list,pusch_timedomainresourceallocation_msg3);
|
|
||||||
}
|
}
|
||||||
|
if (ul_symb>1) {
|
||||||
|
// UL TDA index 2 for mixed slot (TDD)
|
||||||
|
asn1cSeqAdd(&pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list,
|
||||||
|
set_TimeDomainResourceAllocation(k2, 2, ul_symb));
|
||||||
|
}
|
||||||
|
// UL TDA index 3 for msg3 in the mixed slot (TDD)
|
||||||
|
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);
|
||||||
|
int nb_slots_per_period = ((1 << mu) * 10) / nb_periods_per_frame;
|
||||||
|
int k2_msg3 = nb_slots_per_period - DELTA[mu];
|
||||||
|
struct NR_PUSCH_TimeDomainResourceAllocation *puschTdrAllocMsg3 = set_TimeDomainResourceAllocation(k2_msg3, 3, ul_symb);
|
||||||
|
if (*puschTdrAllocMsg3->k2 < min_fb_delay)
|
||||||
|
*puschTdrAllocMsg3->k2 += nb_slots_per_period;
|
||||||
|
AssertFatal(*puschTdrAllocMsg3->k2 < 33,
|
||||||
|
"Computed k2 for msg3 %ld is larger than the range allowed by RRC (0..32)\n",
|
||||||
|
*puschTdrAllocMsg3->k2);
|
||||||
|
asn1cSeqAdd(&pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list, puschTdrAllocMsg3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1118,10 +1204,10 @@ void set_pucch_power_config(NR_PUCCH_Config_t *pucch_Config, int do_csirs) {
|
|||||||
|
|
||||||
static void set_SR_periodandoffset(NR_SchedulingRequestResourceConfig_t *schedulingRequestResourceConfig, const NR_ServingCellConfigCommon_t *scc, int scs)
|
static void set_SR_periodandoffset(NR_SchedulingRequestResourceConfig_t *schedulingRequestResourceConfig, const NR_ServingCellConfigCommon_t *scc, int scs)
|
||||||
{
|
{
|
||||||
const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
|
const frame_structure_t *fs = &RC.nrmac[0]->frame_structure;
|
||||||
int sr_slot = 1; // in FDD SR in slot 1
|
int sr_slot = 1; // in FDD SR in slot 1
|
||||||
if(tdd)
|
if (fs->is_tdd)
|
||||||
sr_slot = get_first_ul_slot(tdd->nrofDownlinkSlots, tdd->nrofDownlinkSymbols, tdd->nrofUplinkSymbols);
|
sr_slot = get_first_ul_slot(fs, true);
|
||||||
|
|
||||||
schedulingRequestResourceConfig->periodicityAndOffset = calloc(1,sizeof(*schedulingRequestResourceConfig->periodicityAndOffset));
|
schedulingRequestResourceConfig->periodicityAndOffset = calloc(1,sizeof(*schedulingRequestResourceConfig->periodicityAndOffset));
|
||||||
|
|
||||||
@@ -1581,15 +1667,14 @@ static void set_csi_meas_periodicity(const NR_ServingCellConfigCommon_t *scc,
|
|||||||
int curr_bwp,
|
int curr_bwp,
|
||||||
bool is_rsrp)
|
bool is_rsrp)
|
||||||
{
|
{
|
||||||
const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
|
const int ideal_period = set_ideal_period(true);
|
||||||
const int n_slots_frame = slotsperframe[*scc->ssbSubcarrierSpacing];
|
|
||||||
const int n_ul_slots_period = tdd ? (tdd->nrofUplinkSlots + (tdd->nrofUplinkSymbols > 0)) : n_slots_frame;
|
|
||||||
const int n_slots_period = tdd ? n_slots_frame / get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity) : n_slots_frame;
|
|
||||||
const int ideal_period = set_ideal_period(n_slots_period, n_ul_slots_period);
|
|
||||||
const int first_ul_slot_period = tdd ? get_first_ul_slot(tdd->nrofDownlinkSlots, tdd->nrofDownlinkSymbols, tdd->nrofUplinkSymbols) : 0;
|
|
||||||
const int num_pucch2 = get_nb_pucch2_per_slot(scc, curr_bwp);
|
const int num_pucch2 = get_nb_pucch2_per_slot(scc, curr_bwp);
|
||||||
const int idx = (uid * 2 / num_pucch2) + is_rsrp;
|
const int idx = (uid * 2 / num_pucch2) + is_rsrp;
|
||||||
const int offset = first_ul_slot_period + idx % n_ul_slots_period + (idx / n_ul_slots_period) * n_slots_period;
|
|
||||||
|
frame_structure_t *fs = &RC.nrmac[0]->frame_structure;
|
||||||
|
int offset = get_ul_slot_offset(fs, idx, true);
|
||||||
|
|
||||||
|
LOG_D(NR_MAC, "set_csi_meas_periodicity: uid = %d, offset = %d, ideal_period = %d", uid, offset, ideal_period);
|
||||||
AssertFatal(offset < 320, "Not enough UL slots to accomodate all possible UEs. Need to rework the implementation\n");
|
AssertFatal(offset < 320, "Not enough UL slots to accomodate all possible UEs. Need to rework the implementation\n");
|
||||||
|
|
||||||
if (ideal_period < 5) {
|
if (ideal_period < 5) {
|
||||||
@@ -2499,7 +2584,10 @@ NR_BCCH_DL_SCH_Message_t *get_SIB1_NR(const NR_ServingCellConfigCommon_t *scc,
|
|||||||
AssertFatal(ServCellCom->tdd_UL_DL_ConfigurationCommon != NULL, "out of memory\n");
|
AssertFatal(ServCellCom->tdd_UL_DL_ConfigurationCommon != NULL, "out of memory\n");
|
||||||
ServCellCom->tdd_UL_DL_ConfigurationCommon->referenceSubcarrierSpacing = scc->tdd_UL_DL_ConfigurationCommon->referenceSubcarrierSpacing;
|
ServCellCom->tdd_UL_DL_ConfigurationCommon->referenceSubcarrierSpacing = scc->tdd_UL_DL_ConfigurationCommon->referenceSubcarrierSpacing;
|
||||||
ServCellCom->tdd_UL_DL_ConfigurationCommon->pattern1 = scc->tdd_UL_DL_ConfigurationCommon->pattern1;
|
ServCellCom->tdd_UL_DL_ConfigurationCommon->pattern1 = scc->tdd_UL_DL_ConfigurationCommon->pattern1;
|
||||||
ServCellCom->tdd_UL_DL_ConfigurationCommon->pattern2 = scc->tdd_UL_DL_ConfigurationCommon->pattern2;
|
if (scc->tdd_UL_DL_ConfigurationCommon->pattern2) {
|
||||||
|
ServCellCom->tdd_UL_DL_ConfigurationCommon->pattern2 = calloc_or_fail(1, sizeof(struct NR_TDD_UL_DL_Pattern));
|
||||||
|
*ServCellCom->tdd_UL_DL_ConfigurationCommon->pattern2 = *scc->tdd_UL_DL_ConfigurationCommon->pattern2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ServCellCom->ss_PBCH_BlockPower = scc->ss_PBCH_BlockPower;
|
ServCellCom->ss_PBCH_BlockPower = scc->ss_PBCH_BlockPower;
|
||||||
|
|
||||||
|
|||||||
@@ -112,5 +112,6 @@ NR_CellGroupConfig_t *get_default_secondaryCellGroup(const NR_ServingCellConfigC
|
|||||||
int uid);
|
int uid);
|
||||||
|
|
||||||
NR_ReconfigurationWithSync_t *get_reconfiguration_with_sync(rnti_t rnti, uid_t uid, const NR_ServingCellConfigCommon_t *scc);
|
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
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,247 @@
|
|||||||
|
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";
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user