diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h index c92851f4e5..dc2f8eef83 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h @@ -22,6 +22,8 @@ #define NFAPI_MAX_NUM_UCI_INDICATION 8 #define NFAPI_MAX_NUM_GROUPS 8 #define NFAPI_MAX_NUM_CB 8 +#define NFAPI_MAX_NUM_PRGS 1 +#define NFAPI_MAX_NUM_BG_IF 1 // Extension to the generic structures for single tlv values @@ -725,7 +727,7 @@ typedef struct typedef struct { uint16_t pm_idx;//Index to precoding matrix (PM) pre-stored at cell configuration. Note: If precoding is not used this parameter should be set to 0. Value: 0->65535. - nfapi_nr_dig_bf_interface_t dig_bf_interface_list[1];//max dig_bf_interfaces + nfapi_nr_dig_bf_interface_t dig_bf_interface_list[NFAPI_MAX_NUM_BG_IF];//max dig_bf_interfaces }nfapi_nr_tx_precoding_and_beamforming_number_of_prgs_t; @@ -736,7 +738,7 @@ typedef struct uint16_t prg_size;//Size in RBs of a precoding resource block group (PRG) – to which same precoding and digital beamforming gets applied. Value: 1->275 //watchout: dig_bf_interfaces here, in table 3-53 it's dig_bf_interface uint8_t dig_bf_interfaces;//Number of STD ant ports (parallel streams) feeding into the digBF Value: 0->255 - nfapi_nr_tx_precoding_and_beamforming_number_of_prgs_t prgs_list[1];//max prg_size + nfapi_nr_tx_precoding_and_beamforming_number_of_prgs_t prgs_list[NFAPI_MAX_NUM_PRGS];//max prg_size }nfapi_nr_tx_precoding_and_beamforming_t; @@ -1141,7 +1143,7 @@ typedef struct { //for prach_pdu: typedef struct { - nfapi_nr_dig_bf_interface_t* dig_bf_interface_list; + nfapi_nr_dig_bf_interface_t dig_bf_interface_list[NFAPI_MAX_NUM_BG_IF]; } nfapi_nr_ul_beamforming_number_of_prgs_t; typedef struct @@ -1150,7 +1152,7 @@ typedef struct uint16_t num_prgs; // Number of PRGs spanning this allocation. Value : 1->275 uint16_t prg_size; // Size in RBs of a precoding resource block group (PRG) – to which the same digital beamforming gets applied. Value: 1->275 uint8_t dig_bf_interface; // Number of logical antenna ports (parallel streams) resulting from the Rx combining. Value: 0->255 - nfapi_nr_ul_beamforming_number_of_prgs_t *prgs_list; + nfapi_nr_ul_beamforming_number_of_prgs_t prgs_list[NFAPI_MAX_NUM_PRGS]; } nfapi_nr_ul_beamforming_t; typedef struct diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c index 9622cd7f5e..b0d197be2a 100644 --- a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c +++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c @@ -4772,15 +4772,6 @@ static uint8_t unpack_ul_tti_request_prach_pdu(void *tlv, uint8_t **ppReadPacked && pull8(ppReadPackedMsg, &prach_pdu->beamforming.dig_bf_interface, end))) { return 0; } - if (prach_pdu->beamforming.num_prgs > 0) { - prach_pdu->beamforming.prgs_list = calloc(prach_pdu->beamforming.num_prgs, sizeof(*prach_pdu->beamforming.prgs_list)); - if (prach_pdu->beamforming.dig_bf_interface > 0) { - for(int prg_idx = 0; prg_idx < prach_pdu->beamforming.num_prgs;prg_idx++){ - prach_pdu->beamforming.prgs_list[prg_idx].dig_bf_interface_list = - calloc(prach_pdu->beamforming.dig_bf_interface, sizeof(*prach_pdu->beamforming.prgs_list[0].dig_bf_interface_list)); - } - } - } for (int prg = 0; prg < prach_pdu->beamforming.num_prgs; prg++) { for (int digBFInterface = 0; digBFInterface < prach_pdu->beamforming.dig_bf_interface; digBFInterface++) { if (!pull16(ppReadPackedMsg, &prach_pdu->beamforming.prgs_list[prg].dig_bf_interface_list[digBFInterface].beam_idx, end)) { diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 73f71fad25..6e89313762 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -48,17 +48,6 @@ extern uint8_t nfapi_mode; void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame,int slot, nfapi_nr_dl_tti_ssb_pdu ssb_pdu) { NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; - nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; - c16_t **txdataF = gNB->common_vars.txdataF; - uint8_t n_hf; - int txdataF_offset = slot*fp->samples_per_slot_wCP; - uint16_t slots_per_hf = (fp->slots_per_frame) >> 1; - - if (slotgNB_config; const int scs = cfg->ssb_config.scs_common.value; const int prb_offset = (fp->freq_range == FR1) ? ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA >> scs : ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA >> (scs - 2); @@ -107,9 +97,14 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame,int slot, nfapi_nr fp->ssb_start_subcarrier); LOG_D(PHY,"SS TX: frame %d, slot %d, start_symbol %d\n",frame,slot, ssb_start_symbol); + c16_t **txdataF = gNB->common_vars.txdataF; + int txdataF_offset = slot * fp->samples_per_slot_wCP; nr_generate_pss(&txdataF[0][txdataF_offset], gNB->TX_AMP, ssb_start_symbol, cfg, fp); nr_generate_sss(&txdataF[0][txdataF_offset], gNB->TX_AMP, ssb_start_symbol, cfg, fp); + uint16_t slots_per_hf = (fp->slots_per_frame) >> 1; + int n_hf = slot < slots_per_hf ? 0 : 1; + int hf = fp->Lmax == 4 ? n_hf : 0; nr_generate_pbch_dmrs(nr_gold_pbch(fp->Lmax, gNB->gNB_config.cell_config.phy_cell_id.value, hf, ssb_index & 7), &txdataF[0][txdataF_offset], @@ -129,9 +124,9 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame,int slot, nfapi_nr #endif // Beam_id is currently used only for FR2 - if (fp->freq_range == FR2){ - LOG_D(PHY,"slot %d, ssb_index %d, beam %d\n",slot,ssb_index,cfg->ssb_table.ssb_beam_id_list[ssb_index].beam_id.value); - for (int j=0;jsymbols_per_slot;j++) + if (fp->freq_range == FR2) { + LOG_D(PHY,"slot %d, ssb_index %d, beam %d\n", slot, ssb_index, cfg->ssb_table.ssb_beam_id_list[ssb_index].beam_id.value); + for (int j = 0; j < fp->symbols_per_slot; j++) gNB->common_vars.beam_id[0][slot*fp->symbols_per_slot+j] = cfg->ssb_table.ssb_beam_id_list[ssb_index].beam_id.value; } @@ -149,25 +144,24 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame,int slot, nfapi_nr void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx, int frame, int slot, - int do_meas) { - - int aa; + int do_meas) +{ PHY_VARS_gNB *gNB = msgTx->gNB; - NR_DL_FRAME_PARMS *fp=&gNB->frame_parms; + NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; int slot_prs = 0; - int txdataF_offset = slot*fp->samples_per_slot_wCP; + int txdataF_offset = slot * fp->samples_per_slot_wCP; prs_config_t *prs_config = NULL; - if ((cfg->cell_config.frame_duplex_type.value == TDD) && - (nr_slot_select(cfg,frame,slot) == NR_UPLINK_SLOT)) return; + if ((cfg->cell_config.frame_duplex_type.value == TDD) && (nr_slot_select(cfg,frame,slot) == NR_UPLINK_SLOT)) + return; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_TX + gNB->CC_id, 1); // clear the transmit data array and beam index for the current slot - for (aa=0; aacarrier_config.num_tx_ant.value; aa++) { - memset(&gNB->common_vars.txdataF[aa][txdataF_offset],0,fp->samples_per_slot_wCP*sizeof(int32_t)); - memset(&gNB->common_vars.beam_id[aa][slot*fp->symbols_per_slot],255,fp->symbols_per_slot*sizeof(uint8_t)); + for (int aa = 0; aa < cfg->carrier_config.num_tx_ant.value; aa++) { + memset(&gNB->common_vars.txdataF[aa][txdataF_offset], 0, fp->samples_per_slot_wCP*sizeof(int32_t)); + memset(&gNB->common_vars.beam_id[aa][slot * fp->symbols_per_slot], 255, fp->symbols_per_slot*sizeof(uint8_t)); } // Check for PRS slot - section 7.4.1.7.4 in 3GPP rel16 38.211 @@ -186,9 +180,9 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx, } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_COMMON_TX,1); - for (int i=0; iLmax; i++) { + for (int i = 0; i < fp->Lmax; i++) { if (msgTx->ssb[i].active) { - nr_common_signal_procedures(gNB,frame,slot,msgTx->ssb[i].ssb_pdu); + nr_common_signal_procedures(gNB, frame, slot, msgTx->ssb[i].ssb_pdu); msgTx->ssb[i].active = false; } } @@ -242,7 +236,7 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx, //apply the OFDM symbol rotation here if (gNB->phase_comp) { - for (aa=0; aacarrier_config.num_tx_ant.value; aa++) { + for (int aa = 0; aa < cfg->carrier_config.num_tx_ant.value; aa++) { apply_nr_rotation_TX(fp, &gNB->common_vars.txdataF[aa][txdataF_offset], fp->symbol_rotation[0], diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h index 1dff70618e..dc6001e877 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h @@ -474,7 +474,6 @@ typedef struct Type0_PDCCH_CSS_config_s { uint32_t first_symbol_index; uint32_t search_space_duration; uint32_t search_space_frame_period; // in slots - uint32_t ssb_length; uint32_t ssb_index; int32_t cset_start_rb; NR_SubcarrierSpacing_t scs_pdcch; diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index 7b65533048..f31ac7cb95 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -532,6 +532,8 @@ static void config_common(gNB_MAC_INST *nrmac, nr_pdsch_AntennaPorts_t pdsch_AntennaPorts = config->pdsch_AntennaPorts; int num_pdsch_antenna_ports = pdsch_AntennaPorts.N1 * pdsch_AntennaPorts.N2 * pdsch_AntennaPorts.XP; cfg->carrier_config.num_tx_ant.value = num_pdsch_antenna_ports; + if(nrmac->beam_info.beam_allocation) // analog beamforming + cfg->carrier_config.num_tx_ant.value *= nrmac->beam_info.beams_per_period; AssertFatal(num_pdsch_antenna_ports > 0 && num_pdsch_antenna_ports < 33, "pdsch_AntennaPorts in 1...32\n"); cfg->carrier_config.num_tx_ant.tl.tag = NFAPI_NR_CONFIG_NUM_TX_ANT_TAG; @@ -558,14 +560,14 @@ static void config_common(gNB_MAC_INST *nrmac, AssertFatal(pusch_AntennaPorts > 0 && pusch_AntennaPorts < 13, "pusch_AntennaPorts in 1...12\n"); cfg->carrier_config.num_rx_ant.tl.tag = NFAPI_NR_CONFIG_NUM_RX_ANT_TAG; LOG_I(NR_MAC, - "Set RX antenna number to %d, Set TX antenna number to %d (num ssb %d: %x,%x)\n", + "Set TX antenna number to %d, Set RX antenna number to %d (num ssb %d: %x,%x)\n", cfg->carrier_config.num_tx_ant.value, cfg->carrier_config.num_rx_ant.value, num_ssb, cfg->ssb_table.ssb_mask_list[0].ssb_mask.value, cfg->ssb_table.ssb_mask_list[1].ssb_mask.value); AssertFatal(cfg->carrier_config.num_tx_ant.value > 0, - "carrier_config.num_tx_ant.value %d !\n", + "carrier_config.num_tx_ant.value %d!\n", cfg->carrier_config.num_tx_ant.value); cfg->num_tlv++; cfg->num_tlv++; @@ -678,6 +680,7 @@ void nr_mac_config_scc(gNB_MAC_INST *nrmac, NR_ServingCellConfigCommon_t *scc, c LOG_I(NR_MAC, "Configuring common parameters from NR ServingCellConfig\n"); config_common(nrmac, config, scc); + fapi_beam_index_allocation(scc, nrmac); if (NFAPI_MODE == NFAPI_MONOLITHIC) { // nothing to be sent in the other cases diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index 7f364235ad..af07ecfb54 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -92,49 +92,6 @@ void clear_nr_nfapi_information(gNB_MAC_INST *gNB, LOG_D(NR_MAC, "%d.%d UL_tti_req_ahead SFN.slot = %d.%d for index %d \n", frameP, slotP, future_ul_tti_req->SFN, future_ul_tti_req->Slot, prev_slot % size); /* future_ul_tti_req->Slot is fixed! */ for (int i = 0; i < future_ul_tti_req->n_pdus; i++) { - switch(future_ul_tti_req->pdus_list[i].pdu_type){ - case NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE: - if(future_ul_tti_req->pdus_list[i].prach_pdu.beamforming.prgs_list){ - for (int j = 0; j < future_ul_tti_req->pdus_list[i].prach_pdu.beamforming.num_prgs; ++j) { - if(future_ul_tti_req->pdus_list[i].prach_pdu.beamforming.prgs_list[j].dig_bf_interface_list){ - free(future_ul_tti_req->pdus_list[i].prach_pdu.beamforming.prgs_list[j].dig_bf_interface_list); - } - } - free(future_ul_tti_req->pdus_list[i].prach_pdu.beamforming.prgs_list); - } - break; - case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE: - if(future_ul_tti_req->pdus_list[i].pusch_pdu.beamforming.prgs_list){ - for (int j = 0; j < future_ul_tti_req->pdus_list[i].pusch_pdu.beamforming.num_prgs; ++j) { - if(future_ul_tti_req->pdus_list[i].pusch_pdu.beamforming.prgs_list[j].dig_bf_interface_list){ - free(future_ul_tti_req->pdus_list[i].pusch_pdu.beamforming.prgs_list[j].dig_bf_interface_list); - } - } - free(future_ul_tti_req->pdus_list[i].pusch_pdu.beamforming.prgs_list); - } - break; - case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE: - if(future_ul_tti_req->pdus_list[i].pucch_pdu.beamforming.prgs_list){ - for (int j = 0; j < future_ul_tti_req->pdus_list[i].pucch_pdu.beamforming.num_prgs; ++j) { - if(future_ul_tti_req->pdus_list[i].pucch_pdu.beamforming.prgs_list[j].dig_bf_interface_list){ - free(future_ul_tti_req->pdus_list[i].pucch_pdu.beamforming.prgs_list[j].dig_bf_interface_list); - } - } - free(future_ul_tti_req->pdus_list[i].pucch_pdu.beamforming.prgs_list); - } - break; - case NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE: - if(future_ul_tti_req->pdus_list[i].srs_pdu.beamforming.prgs_list){ - for (int j = 0; j < future_ul_tti_req->pdus_list[i].srs_pdu.beamforming.num_prgs; ++j) { - if(future_ul_tti_req->pdus_list[i].srs_pdu.beamforming.prgs_list[j].dig_bf_interface_list){ - free(future_ul_tti_req->pdus_list[i].srs_pdu.beamforming.prgs_list[j].dig_bf_interface_list); - } - } - free(future_ul_tti_req->pdus_list[i].srs_pdu.beamforming.prgs_list); - } - default: - break; - } future_ul_tti_req->pdus_list[i].pdu_type = 0; future_ul_tti_req->pdus_list[i].pdu_size = 0; } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index ed32fe3669..51420293ec 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -54,16 +54,13 @@ extern uint16_t sl_ahead; // forward declaration of functions used in this file static void fill_msg3_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu, NR_ServingCellConfigCommon_t *scc, - int round, + const NR_RA_t *ra, int startSymbolAndLength, - rnti_t rnti, int scs, int bwp_size, int bwp_start, int mappingtype, - int fh, - int msg3_first_rb, - int msg3_nb_rb); + int fh); static void nr_fill_rar(uint8_t Mod_idP, NR_RA_t *ra, uint8_t *dlsch_buffer, nfapi_nr_pusch_pdu_t *pusch_pdu); static const uint8_t DELTA[4] = {2, 3, 4, 6}; @@ -224,7 +221,7 @@ void find_SSB_and_RO_available(gNB_MAC_INST *nrmac) float num_ssb_per_RO = ssb_per_rach_occasion[cfg->prach_config.ssb_per_rach.value]; uint8_t fdm = cfg->prach_config.num_prach_fd_occasions.value; - uint64_t L_ssb = (((uint64_t) cfg->ssb_table.ssb_mask_list[0].ssb_mask.value)<<32) | cfg->ssb_table.ssb_mask_list[1].ssb_mask.value ; + uint64_t L_ssb = (((uint64_t) cfg->ssb_table.ssb_mask_list[0].ssb_mask.value) << 32) | cfg->ssb_table.ssb_mask_list[1].ssb_mask.value; uint32_t total_RA_occasions = N_RA_sfn * N_t_slot * N_RA_slot * fdm; for(int i = 0; i < 64; i++) { @@ -330,15 +327,23 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP continue; float num_ssb_per_RO = ssb_per_rach_occasion[cfg->prach_config.ssb_per_rach.value]; + int beam_index = 0; if(num_ssb_per_RO <= 1) { - int ssb_index = (int) (prach_occasion_id / (int)(1 / num_ssb_per_RO)) % cc->num_active_ssb; - beam = beam_allocation_procedure(&gNB->beam_info, frameP, slotP, ssb_index, nr_slots_per_frame[mu]); - AssertFatal(beam.idx >= 0, "Cannot allocate PRACH corresponding to SSB %d in any available beam\n", ssb_index); + // ordered ssb number + int n_ssb = (int) (prach_occasion_id / (int)(1 / num_ssb_per_RO)) % cc->num_active_ssb; + // fapi beam index + beam_index = get_fapi_beamforming_index(gNB, cc->ssb_index[n_ssb]); + // multi-beam allocation structure + beam = beam_allocation_procedure(&gNB->beam_info, frameP, slotP, beam_index, nr_slots_per_frame[mu]); + AssertFatal(beam.idx >= 0, "Cannot allocate PRACH corresponding to %d SSB transmitted in any available beam\n", n_ssb + 1); } else { int first_ssb_index = (prach_occasion_id * (int)num_ssb_per_RO) % cc->num_active_ssb; for(int j = first_ssb_index; j < first_ssb_index + num_ssb_per_RO; j++) { - beam = beam_allocation_procedure(&gNB->beam_info, frameP, slotP, j, nr_slots_per_frame[mu]); + // fapi beam index + beam_index = get_fapi_beamforming_index(gNB, cc->ssb_index[j]); + // multi-beam allocation structure + beam = beam_allocation_procedure(&gNB->beam_info, frameP, slotP, beam_index, nr_slots_per_frame[mu]); AssertFatal(beam.idx >= 0, "Cannot allocate PRACH corresponding to SSB %d in any available beam\n", j); } } @@ -361,6 +366,11 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP format0, rach_ConfigCommon->restrictedSetConfig); + prach_pdu->beamforming.num_prgs = 0; + prach_pdu->beamforming.prg_size = 0; + prach_pdu->beamforming.dig_bf_interface = 1; + prach_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = beam_index; + LOG_D(NR_MAC, "Frame %d, Slot %d: Prach Occasion id = %u fdm index = %u start symbol = %u slot index = %u subframe index = %u \n", frameP, @@ -548,8 +558,9 @@ void nr_initiate_ra_proc(module_id_t module_idP, NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; configure_UE_BWP(nr_mac, scc, NULL, ra, NULL, -1, -1); - uint8_t beam_index = ssb_index_from_prach(module_idP, frameP, slotP, preamble_index, freq_index, symbol); - ra->beam_id = cc->ssb_index[beam_index]; + // return current SSB order in the list of tranmitted SSBs + int n_ssb = ssb_index_from_prach(module_idP, frameP, slotP, preamble_index, freq_index, symbol); + ra->beam_id = get_fapi_beamforming_index(nr_mac, cc->ssb_index[n_ssb]); NR_SCHED_UNLOCK(&nr_mac->sched_lock); @@ -654,13 +665,7 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP, nfapi_nr_pusch_pdu_t *pusch_pdu = &future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pusch_pdu; memset(pusch_pdu, 0, sizeof(nfapi_nr_pusch_pdu_t)); - fill_msg3_pusch_pdu(pusch_pdu, scc, - ra->msg3_round, - startSymbolAndLength, - ra->rnti, mu, - BWPSize, BWPStart, - mappingtype, fh, - rbStart, ra->msg3_nb_rb); + fill_msg3_pusch_pdu(pusch_pdu, scc, ra, startSymbolAndLength, mu, BWPSize, BWPStart, mappingtype, fh); future_ul_tti_req->n_pdus += 1; // generation of DCI 0_0 to schedule msg3 retransmission @@ -706,6 +711,12 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP, dci_pdu->beta_PDCCH_1_0 = 0; dci_pdu->powerControlOffsetSS = 1; + dci_pdu->precodingAndBeamforming.num_prgs = 0; + dci_pdu->precodingAndBeamforming.prg_size = 0; + dci_pdu->precodingAndBeamforming.dig_bf_interfaces = 1; + dci_pdu->precodingAndBeamforming.prgs_list[0].pm_idx = 0; + dci_pdu->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = ra->beam_id; + dci_pdu_rel15_t uldci_payload={0}; config_uldci(sc_info, @@ -883,16 +894,13 @@ static void nr_get_Msg3alloc(module_id_t module_id, static void fill_msg3_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu, NR_ServingCellConfigCommon_t *scc, - int round, + const NR_RA_t *ra, int startSymbolAndLength, - rnti_t rnti, int scs, int bwp_size, int bwp_start, int mappingtype, - int fh, - int msg3_first_rb, - int msg3_nb_rb) + int fh) { int start_symbol_index,nr_of_symbols; @@ -900,7 +908,7 @@ static void fill_msg3_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu, int mcsindex = -1; // init value pusch_pdu->pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA; - pusch_pdu->rnti = rnti; + pusch_pdu->rnti = ra->rnti; pusch_pdu->handle = 0; pusch_pdu->bwp_start = bwp_start; pusch_pdu->bwp_size = bwp_size; @@ -928,11 +936,11 @@ static void fill_msg3_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu, pusch_pdu->num_dmrs_cdm_grps_no_data = 2; // no data in dmrs symbols as in 6.2.2 in 38.214 pusch_pdu->resource_alloc = 1; //type 1 memset(pusch_pdu->rb_bitmap, 0, sizeof(pusch_pdu->rb_bitmap)); - pusch_pdu->rb_start = msg3_first_rb; - if (msg3_nb_rb > pusch_pdu->bwp_size) - AssertFatal(1==0,"MSG3 allocated number of RBs exceed the BWP size\n"); + pusch_pdu->rb_start = ra->msg3_first_rb; + if (ra->msg3_nb_rb > pusch_pdu->bwp_size) + AssertFatal(false, "MSG3 allocated number of RBs exceed the BWP size\n"); else - pusch_pdu->rb_size = msg3_nb_rb; + pusch_pdu->rb_size = ra->msg3_nb_rb; pusch_pdu->vrb_to_prb_mapping = 0; pusch_pdu->frequency_hopping = fh; @@ -945,27 +953,17 @@ static void fill_msg3_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu, pusch_pdu->start_symbol_index = start_symbol_index; pusch_pdu->nr_of_symbols = nr_of_symbols; //Optional Data only included if indicated in pduBitmap - pusch_pdu->pusch_data.rv_index = nr_rv_round_map[round%4]; + pusch_pdu->pusch_data.rv_index = nr_rv_round_map[ra->msg3_round % 4]; pusch_pdu->pusch_data.harq_process_id = 0; - pusch_pdu->pusch_data.new_data_indicator = (round == 0) ? 1 : 0;; + pusch_pdu->pusch_data.new_data_indicator = (ra->msg3_round == 0) ? 1 : 0;; pusch_pdu->pusch_data.num_cb = 0; // Beamforming pusch_pdu->beamforming.num_prgs = 0; pusch_pdu->beamforming.prg_size = 0; // bwp_size; - pusch_pdu->beamforming.dig_bf_interface = 0; - if (pusch_pdu->beamforming.num_prgs > 0) { - if (pusch_pdu->beamforming.prgs_list == NULL) { - pusch_pdu->beamforming.prgs_list = calloc(pusch_pdu->beamforming.num_prgs, sizeof(*pusch_pdu->beamforming.prgs_list)); - } - if (pusch_pdu->beamforming.dig_bf_interface > 0) { - if (pusch_pdu->beamforming.prgs_list[0].dig_bf_interface_list == NULL) { - pusch_pdu->beamforming.prgs_list[0].dig_bf_interface_list = - calloc(pusch_pdu->beamforming.dig_bf_interface, sizeof(*pusch_pdu->beamforming.prgs_list[0].dig_bf_interface_list)); - } - } - pusch_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = 0; - } + pusch_pdu->beamforming.dig_bf_interface = 1; + pusch_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = ra->beam_id; + int num_dmrs_symb = 0; for(int i = start_symbol_index; i < start_symbol_index+nr_of_symbols; i++) num_dmrs_symb += (pusch_pdu->ul_dmrs_symb_pos >> i) & 1; @@ -1048,13 +1046,7 @@ static void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_f ra->msg3_first_rb, ra->msg3_round); - fill_msg3_pusch_pdu(pusch_pdu,scc, - ra->msg3_round, - startSymbolAndLength, - ra->rnti, scs, - ibwp_size, ra->msg3_bwp_start, - mappingtype, fh, - ra->msg3_first_rb, ra->msg3_nb_rb); + fill_msg3_pusch_pdu(pusch_pdu, scc, ra, startSymbolAndLength, scs, ibwp_size, ra->msg3_bwp_start, mappingtype, fh); future_ul_tti_req->n_pdus += 1; // calling function to fill rar message @@ -1271,7 +1263,7 @@ static void nr_generate_Msg2(module_id_t module_idP, BWPStart = dl_bwp->BWPStart; BWPSize = sc_info->initial_dl_BWPSize; } else { - type0_PDCCH_CSS_config = &nr_mac->type0_PDCCH_CSS_config[ra->beam_id]; + type0_PDCCH_CSS_config = &nr_mac->type0_PDCCH_CSS_config[cc->ssb_index[ra->beam_id]]; BWPStart = type0_PDCCH_CSS_config->cset_start_rb; BWPSize = type0_PDCCH_CSS_config->num_rbs; } @@ -1354,7 +1346,7 @@ static void nr_generate_Msg2(module_id_t module_idP, pdsch_pdu_rel15->precodingAndBeamforming.prg_size = 0; pdsch_pdu_rel15->precodingAndBeamforming.dig_bf_interfaces = 0; pdsch_pdu_rel15->precodingAndBeamforming.prgs_list[0].pm_idx = 0; - pdsch_pdu_rel15->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = 0; + pdsch_pdu_rel15->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = ra->beam_id; LOG_A(NR_MAC, "UE %04x: %d.%d Generating RA-Msg2 DCI, RA RNTI 0x%x, state %d, CoreSetType %d, RAPID %d\n", @@ -1438,6 +1430,12 @@ static void nr_generate_Msg2(module_id_t module_idP, dci_pdu->beta_PDCCH_1_0 = 0; dci_pdu->powerControlOffsetSS = 1; + dci_pdu->precodingAndBeamforming.num_prgs = 0; + dci_pdu->precodingAndBeamforming.prg_size = 0; + dci_pdu->precodingAndBeamforming.dig_bf_interfaces = 1; + dci_pdu->precodingAndBeamforming.prgs_list[0].pm_idx = 0; + dci_pdu->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = ra->beam_id; + dci_pdu_rel15_t dci_payload; dci_payload.frequency_domain_assignment.val = PRBalloc_to_locationandbandwidth0(pdsch_pdu_rel15->rbSize, pdsch_pdu_rel15->rbStart, BWPSize); @@ -1603,7 +1601,7 @@ static void prepare_dl_pdus(gNB_MAC_INST *nr_mac, BWPStart = dl_bwp->BWPStart; BWPSize = dl_bwp->BWPSize; } else { - type0_PDCCH_CSS_config = &nr_mac->type0_PDCCH_CSS_config[ra->beam_id]; + type0_PDCCH_CSS_config = &nr_mac->type0_PDCCH_CSS_config[cc->ssb_index[ra->beam_id]]; BWPStart = type0_PDCCH_CSS_config->cset_start_rb; BWPSize = type0_PDCCH_CSS_config->num_rbs; } @@ -1665,6 +1663,12 @@ static void prepare_dl_pdus(gNB_MAC_INST *nr_mac, dci_pdu->beta_PDCCH_1_0 = 0; dci_pdu->powerControlOffsetSS = 1; + dci_pdu->precodingAndBeamforming.num_prgs = 0; + dci_pdu->precodingAndBeamforming.prg_size = 0; + dci_pdu->precodingAndBeamforming.dig_bf_interfaces = 1; + dci_pdu->precodingAndBeamforming.prgs_list[0].pm_idx = 0; + dci_pdu->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = ra->beam_id; + dci_pdu_rel15_t dci_payload; dci_payload.frequency_domain_assignment.val = PRBalloc_to_locationandbandwidth0(pdsch_pdu_rel15->rbSize, pdsch_pdu_rel15->rbStart, @@ -1799,7 +1803,7 @@ static void nr_generate_Msg4(module_id_t module_idP, BWPStart = dl_bwp->BWPStart; BWPSize = dl_bwp->BWPSize; } else { - type0_PDCCH_CSS_config = &nr_mac->type0_PDCCH_CSS_config[ra->beam_id]; + type0_PDCCH_CSS_config = &nr_mac->type0_PDCCH_CSS_config[cc->ssb_index[ra->beam_id]]; BWPStart = type0_PDCCH_CSS_config->cset_start_rb; BWPSize = type0_PDCCH_CSS_config->num_rbs; } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c index 18ce58f2d4..1a8086db47 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c @@ -52,41 +52,43 @@ static void schedule_ssb(frame_t frame, NR_ServingCellConfigCommon_t *scc, nfapi_nr_dl_tti_request_body_t *dl_req, int i_ssb, + int beam_index, uint8_t scoffset, uint16_t offset_pointa, uint32_t payload) { - uint8_t beam_index = 0; - nfapi_nr_dl_tti_request_pdu_t *dl_config_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; - memset((void *) dl_config_pdu, 0,sizeof(nfapi_nr_dl_tti_request_pdu_t)); - dl_config_pdu->PDUType = NFAPI_NR_DL_TTI_SSB_PDU_TYPE; - dl_config_pdu->PDUSize =2 + sizeof(nfapi_nr_dl_tti_ssb_pdu_rel15_t); + nfapi_nr_dl_tti_request_pdu_t *dl_config_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; + memset((void *) dl_config_pdu, 0, sizeof(nfapi_nr_dl_tti_request_pdu_t)); + dl_config_pdu->PDUType = NFAPI_NR_DL_TTI_SSB_PDU_TYPE; + dl_config_pdu->PDUSize = 2 + sizeof(nfapi_nr_dl_tti_ssb_pdu_rel15_t); - AssertFatal(scc->physCellId!=NULL,"ServingCellConfigCommon->physCellId is null\n"); - AssertFatal(*scc->physCellId < 1008 && *scc->physCellId >=0, "5G physicall cell id out of range: %ld\n", *scc->physCellId); - dl_config_pdu->ssb_pdu.ssb_pdu_rel15.PhysCellId = *scc->physCellId; - dl_config_pdu->ssb_pdu.ssb_pdu_rel15.BetaPss = 0; - dl_config_pdu->ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = i_ssb; - AssertFatal(scc->downlinkConfigCommon!=NULL,"scc->downlinkConfigCommonL is null\n"); - AssertFatal(scc->downlinkConfigCommon->frequencyInfoDL!=NULL,"scc->downlinkConfigCommon->frequencyInfoDL is null\n"); - AssertFatal(scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB!=NULL,"scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB is null\n"); - AssertFatal(scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.count==1,"Frequency Band list does not have 1 element (%d)\n", + AssertFatal(scc->physCellId != NULL,"ServingCellConfigCommon->physCellId is null\n"); + AssertFatal(*scc->physCellId < 1008 && *scc->physCellId >=0, "5G physicall cell id out of range: %ld\n", *scc->physCellId); + dl_config_pdu->ssb_pdu.ssb_pdu_rel15.PhysCellId = *scc->physCellId; + dl_config_pdu->ssb_pdu.ssb_pdu_rel15.BetaPss = 0; + dl_config_pdu->ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = i_ssb; + AssertFatal(scc->downlinkConfigCommon,"scc->downlinkConfigCommonL is null\n"); + AssertFatal(scc->downlinkConfigCommon->frequencyInfoDL,"scc->downlinkConfigCommon->frequencyInfoDL is null\n"); + AssertFatal(scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB, + "scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB is null\n"); + AssertFatal(scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.count == 1, + "Frequency Band list does not have 1 element (%d)\n", scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.count); AssertFatal(scc->ssbSubcarrierSpacing,"ssbSubcarrierSpacing is null\n"); - AssertFatal(scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0],"band is null\n"); + AssertFatal(scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], "band is null\n"); dl_config_pdu->ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset = scoffset; //kSSB - dl_config_pdu->ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA = offset_pointa; - dl_config_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag = 1; - dl_config_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload = payload; - dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.num_prgs=1; - dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.prg_size=275; //1 PRG of max size for analogue beamforming - dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.dig_bf_interfaces=1; + dl_config_pdu->ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA = offset_pointa; + dl_config_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag = 1; + dl_config_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload = payload; + dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.num_prgs = 1; + dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.prg_size = 275; //1 PRG of max size for analogue beamforming + dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.dig_bf_interfaces = 1; dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.prgs_list[0].pm_idx = 0; dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = beam_index; dl_req->nPDUs++; - LOG_D(MAC,"Scheduling ssb %d at frame %d and slot %d\n",i_ssb,frame,slot); + LOG_D(MAC,"Scheduling ssb %d at frame %d and slot %d\n", i_ssb, frame, slot); } static void fill_ssb_vrb_map(NR_COMMON_channels_t *cc, @@ -152,13 +154,12 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, if (ssb_period > 1) // 0 is every half frame ssb_frame_periodicity = 1 << (ssb_period -1); - if (!(frameP%ssb_frame_periodicity) && - ((slotP<(slots_per_frame>>1)) || (ssb_period == 0))) { + if (!(frameP % ssb_frame_periodicity) && ((slotP < (slots_per_frame >> 1)) || (ssb_period == 0))) { // schedule SSB only for given frames according to SSB periodicity // and in first half frame unless periodicity of 5ms int rel_slot; if (ssb_period == 0) // scheduling every half frame - rel_slot = slotP%(slots_per_frame>>1); + rel_slot = slotP % (slots_per_frame >> 1); else rel_slot = slotP; @@ -171,21 +172,20 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, const BIT_STRING_t *mediumBitmap = &scc->ssb_PositionsInBurst->choice.mediumBitmap; const BIT_STRING_t *longBitmap = &scc->ssb_PositionsInBurst->choice.longBitmap; - uint16_t ssb_start_symbol; const int n_slots_frame = nr_slots_per_frame[scs]; - switch (scc->ssb_PositionsInBurst->present) { case 1: // short bitmap (<3GHz) max 4 SSBs for (int i_ssb = 0; i_ssb < 4; i_ssb++) { if ((shortBitmap->buf[0] >> (7 - i_ssb)) & 0x01) { - ssb_start_symbol = get_ssb_start_symbol(band, scs, i_ssb); + uint16_t ssb_start_symbol = get_ssb_start_symbol(band, scs, i_ssb); // if start symbol is in current slot, schedule current SSB, fill VRB map and call get_type0_PDCCH_CSS_config_parameters - if ((ssb_start_symbol / 14) == rel_slot){ - NR_beam_alloc_t beam = beam_allocation_procedure(&gNB->beam_info, frameP, slotP, i_ssb, n_slots_frame); + if ((ssb_start_symbol / 14) == rel_slot) { + int beam_index = get_fapi_beamforming_index(gNB, i_ssb); + NR_beam_alloc_t beam = beam_allocation_procedure(&gNB->beam_info, frameP, slotP, beam_index, n_slots_frame); AssertFatal(beam.idx >= 0, "Cannot allocate SSB %d in any available beam\n", i_ssb); const int prb_offset = offset_pointa >> scs; - schedule_ssb(frameP, slotP, scc, dl_req, i_ssb, ssbSubcarrierOffset, offset_pointa, mib_pdu); + schedule_ssb(frameP, slotP, scc, dl_req, i_ssb, beam_index, ssbSubcarrierOffset, offset_pointa, mib_pdu); fill_ssb_vrb_map(cc, prb_offset, ssbSubcarrierOffset, ssb_start_symbol, CC_id, beam.idx); if (get_softmodem_params()->sa == 1) { get_type0_PDCCH_CSS_config_parameters(&gNB->type0_PDCCH_CSS_config[i_ssb], @@ -210,13 +210,14 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, // medium bitmap (<6GHz) max 8 SSBs for (int i_ssb = 0; i_ssb < 8; i_ssb++) { if ((mediumBitmap->buf[0] >> (7 - i_ssb)) & 0x01) { - ssb_start_symbol = get_ssb_start_symbol(band, scs, i_ssb); + uint16_t ssb_start_symbol = get_ssb_start_symbol(band, scs, i_ssb); // if start symbol is in current slot, schedule current SSB, fill VRB map and call get_type0_PDCCH_CSS_config_parameters - if ((ssb_start_symbol / 14) == rel_slot){ - NR_beam_alloc_t beam = beam_allocation_procedure(&gNB->beam_info, frameP, slotP, i_ssb, n_slots_frame); + if ((ssb_start_symbol / 14) == rel_slot) { + int beam_index = get_fapi_beamforming_index(gNB, i_ssb); + NR_beam_alloc_t beam = beam_allocation_procedure(&gNB->beam_info, frameP, slotP, beam_index, n_slots_frame); AssertFatal(beam.idx >= 0, "Cannot allocate SSB %d in any available beam\n", i_ssb); const int prb_offset = offset_pointa >> scs; - schedule_ssb(frameP, slotP, scc, dl_req, i_ssb, ssbSubcarrierOffset, offset_pointa, mib_pdu); + schedule_ssb(frameP, slotP, scc, dl_req, i_ssb, beam_index, ssbSubcarrierOffset, offset_pointa, mib_pdu); fill_ssb_vrb_map(cc, prb_offset, ssbSubcarrierOffset, ssb_start_symbol, CC_id, beam.idx); if (get_softmodem_params()->sa == 1) { get_type0_PDCCH_CSS_config_parameters(&gNB->type0_PDCCH_CSS_config[i_ssb], @@ -241,13 +242,14 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, // long bitmap FR2 max 64 SSBs for (int i_ssb = 0; i_ssb < 64; i_ssb++) { if ((longBitmap->buf[i_ssb / 8] >> (7 - (i_ssb % 8))) & 0x01) { - ssb_start_symbol = get_ssb_start_symbol(band, scs, i_ssb); + uint16_t ssb_start_symbol = get_ssb_start_symbol(band, scs, i_ssb); // if start symbol is in current slot, schedule current SSB, fill VRB map and call get_type0_PDCCH_CSS_config_parameters - if ((ssb_start_symbol / 14) == rel_slot){ - NR_beam_alloc_t beam = beam_allocation_procedure(&gNB->beam_info, frameP, slotP, i_ssb, n_slots_frame); + if ((ssb_start_symbol / 14) == rel_slot) { + int beam_index = get_fapi_beamforming_index(gNB, i_ssb); + NR_beam_alloc_t beam = beam_allocation_procedure(&gNB->beam_info, frameP, slotP, beam_index, n_slots_frame); AssertFatal(beam.idx >= 0, "Cannot allocate SSB %d in any available beam\n", i_ssb); const int prb_offset = offset_pointa >> (scs-2); // reference 60kHz - schedule_ssb(frameP, slotP, scc, dl_req, i_ssb, ssbSubcarrierOffset, offset_pointa, mib_pdu); + schedule_ssb(frameP, slotP, scc, dl_req, i_ssb, beam_index, ssbSubcarrierOffset, offset_pointa, mib_pdu); fill_ssb_vrb_map(cc, prb_offset, ssbSubcarrierOffset >> (scs - 2), ssb_start_symbol, CC_id, beam.idx); if (get_softmodem_params()->sa == 1) { get_type0_PDCCH_CSS_config_parameters(&gNB->type0_PDCCH_CSS_config[i_ssb], @@ -493,7 +495,8 @@ static void nr_fill_nfapi_dl_SIB_pdu(int Mod_idP, NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config, uint32_t TBS, int StartSymbolIndex, - int NrOfSymbols) + int NrOfSymbols, + int beam_index) { // will set data according to SIB type (SIB1/OtherSI) NR_sched_pdsch_t *pdsch = (sched_ctrlCommon ? &sched_ctrlCommon->sched_pdsch : &sched_osi->sched_pdsch); @@ -526,11 +529,11 @@ static void nr_fill_nfapi_dl_SIB_pdu(int Mod_idP, dl_req->nPDUs += 1; nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15; - pdsch_pdu_rel15->precodingAndBeamforming.num_prgs=0; - pdsch_pdu_rel15->precodingAndBeamforming.prg_size=0; - pdsch_pdu_rel15->precodingAndBeamforming.dig_bf_interfaces=0; + pdsch_pdu_rel15->precodingAndBeamforming.num_prgs = 0; + pdsch_pdu_rel15->precodingAndBeamforming.prg_size = 0; + pdsch_pdu_rel15->precodingAndBeamforming.dig_bf_interfaces = 1; pdsch_pdu_rel15->precodingAndBeamforming.prgs_list[0].pm_idx = 0; - pdsch_pdu_rel15->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = 0; + pdsch_pdu_rel15->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = beam_index; pdcch_pdu_rel15->CoreSetType = NFAPI_NR_CSET_CONFIG_MIB_SIB1; @@ -538,7 +541,7 @@ static void nr_fill_nfapi_dl_SIB_pdu(int Mod_idP, pdsch_pdu_rel15->rnti = SI_RNTI; pdsch_pdu_rel15->pduIndex = pdu_index; - pdsch_pdu_rel15->BWPSize = type0_PDCCH_CSS_config->num_rbs; + pdsch_pdu_rel15->BWPSize = type0_PDCCH_CSS_config->num_rbs; pdsch_pdu_rel15->BWPStart = type0_PDCCH_CSS_config->cset_start_rb; pdsch_pdu_rel15->SubcarrierSpacing = type0_PDCCH_CSS_config->scs_pdcch; @@ -592,6 +595,12 @@ static void nr_fill_nfapi_dl_SIB_pdu(int Mod_idP, dci_pdu->beta_PDCCH_1_0 = 0; dci_pdu->powerControlOffsetSS = 1; + dci_pdu->precodingAndBeamforming.num_prgs = 0; + dci_pdu->precodingAndBeamforming.prg_size = 0; + dci_pdu->precodingAndBeamforming.dig_bf_interfaces = 1; + dci_pdu->precodingAndBeamforming.prgs_list[0].pm_idx = 0; + dci_pdu->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = beam_index; + /* DCI payload */ dci_pdu_rel15_t dci_payload; memset(&dci_payload, 0, sizeof(dci_pdu_rel15_t)); @@ -692,7 +701,8 @@ void schedule_nr_sib1(module_id_t module_idP, (type0_PDCCH_CSS_config->active == true)) { const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; - NR_beam_alloc_t beam = beam_allocation_procedure(&gNB_mac->beam_info, frameP, slotP, i, n_slots_frame); + int beam_index = get_fapi_beamforming_index(gNB_mac, i); + NR_beam_alloc_t beam = beam_allocation_procedure(&gNB_mac->beam_info, frameP, slotP, beam_index, n_slots_frame); AssertFatal(beam.idx >= 0, "Cannot allocate SIB1 corresponding to SSB %d in any available beam\n", i); LOG_D(NR_MAC,"(%d.%d) SIB1 transmission: ssb_index %d\n", frameP, slotP, type0_PDCCH_CSS_config->ssb_index); @@ -729,7 +739,8 @@ void schedule_nr_sib1(module_id_t module_idP, type0_PDCCH_CSS_config, TBS, tda_info.startSymbolIndex, - tda_info.nrOfSymbols); + tda_info.nrOfSymbols, + beam_index); const int ntx_req = TX_req->Number_of_PDUs; nfapi_nr_pdu_t *tx_req = &TX_req->pdu_list[ntx_req]; @@ -829,7 +840,7 @@ void schedule_nr_sib19(module_id_t module_idP, } const int window_length = 10; - for (int i=0; itype0_PDCCH_CSS_config[i]; if(((frameP - 1) % frame == 0) && @@ -837,7 +848,8 @@ void schedule_nr_sib19(module_id_t module_idP, (type0_PDCCH_CSS_config->num_rbs > 0)) { const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; - NR_beam_alloc_t beam = beam_allocation_procedure(&gNB_mac->beam_info, frameP, slotP, i, n_slots_frame); + int beam_index = get_fapi_beamforming_index(gNB_mac, i); + NR_beam_alloc_t beam = beam_allocation_procedure(&gNB_mac->beam_info, frameP, slotP, beam_index, n_slots_frame); AssertFatal(beam.idx >= 0, "Cannot allocate SIB19 corresponding to SSB %d in any available beam\n", i); LOG_D(NR_MAC,"(%d.%d) SIB19 transmission: ssb_index %d\n", frameP, slotP, type0_PDCCH_CSS_config->ssb_index); @@ -873,7 +885,8 @@ void schedule_nr_sib19(module_id_t module_idP, type0_PDCCH_CSS_config, TBS, tda_info.startSymbolIndex, - tda_info.nrOfSymbols); + tda_info.nrOfSymbols, + beam_index); const int ntx_req = TX_req->Number_of_PDUs; nfapi_nr_pdu_t *tx_req = &TX_req->pdu_list[ntx_req]; @@ -901,4 +914,4 @@ void schedule_nr_sib19(module_id_t module_idP, T_BUFFER(sib19_bcch_pdu, sib19_bcch_length)); } } -} \ No newline at end of file +} diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 1307df70ac..4691a6109a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -1136,7 +1136,7 @@ void nr_schedule_ue_spec(module_id_t module_id, pdsch_pdu->precodingAndBeamforming.prg_size = pdsch_pdu->rbSize; pdsch_pdu->precodingAndBeamforming.dig_bf_interfaces = 0; pdsch_pdu->precodingAndBeamforming.prgs_list[0].pm_idx = sched_pdsch->pm_index; - pdsch_pdu->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = 0; + pdsch_pdu->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = UE->UE_beam_index; // TBS_LBRM according to section 5.4.2.1 of 38.212 // TODO: verify the case where maxMIMO_Layers is NULL, in which case // in principle maxMIMO_layers should be given by the maximum number of layers @@ -1196,7 +1196,7 @@ void nr_schedule_ue_spec(module_id_t module_id, dci_pdu->precodingAndBeamforming.prg_size = 0; dci_pdu->precodingAndBeamforming.dig_bf_interfaces = 0; dci_pdu->precodingAndBeamforming.prgs_list[0].pm_idx = 0; - dci_pdu->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = 0; + dci_pdu->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = UE->UE_beam_index; /* DCI payload */ dci_pdu_rel15_t dci_payload; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 4cf6da7433..6051da9d15 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -797,10 +797,12 @@ void config_uldci(const NR_UE_ServingCell_Info_t *sc_info, dci_pdu_rel15->rv = pusch_pdu->pusch_data.rv_index; dci_pdu_rel15->harq_pid.val = pusch_pdu->pusch_data.harq_process_id; dci_pdu_rel15->tpc = tpc; - NR_PUSCH_Config_t *pusch_Config = ul_bwp->pusch_Config; - if (pusch_Config) AssertFatal(pusch_Config->resourceAllocation == NR_PUSCH_Config__resourceAllocation_resourceAllocationType1, - "Only frequency resource allocation type 1 is currently supported\n"); + NR_PUSCH_Config_t *pusch_Config = ul_bwp->pusch_Config; + if (pusch_Config) + AssertFatal(pusch_Config->resourceAllocation == NR_PUSCH_Config__resourceAllocation_resourceAllocationType1, + "Only frequency resource allocation type 1 is currently supported\n"); + switch (dci_format) { case NR_UL_DCI_FORMAT_0_0: dci_pdu_rel15->format_indicator = 0; @@ -1126,18 +1128,7 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t *pucch_pdu, pucch_pdu->beamforming.num_prgs = 0; pucch_pdu->beamforming.prg_size = 0; // pucch_pdu->prb_size; pucch_pdu->beamforming.dig_bf_interface = 0; - if (pucch_pdu->beamforming.num_prgs > 0) { - if (pucch_pdu->beamforming.prgs_list == NULL) { - pucch_pdu->beamforming.prgs_list = calloc(pucch_pdu->beamforming.num_prgs, sizeof(*pucch_pdu->beamforming.prgs_list)); - } - if (pucch_pdu->beamforming.dig_bf_interface > 0) { - if (pucch_pdu->beamforming.prgs_list[0].dig_bf_interface_list == NULL) { - pucch_pdu->beamforming.prgs_list[0].dig_bf_interface_list = - calloc(pucch_pdu->beamforming.dig_bf_interface, sizeof(*pucch_pdu->beamforming.prgs_list[0].dig_bf_interface_list)); - } - } - pucch_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = 0; - } + pucch_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = UE->UE_beam_index; } void set_r_pucch_parms(int rsetindex, @@ -2423,12 +2414,14 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac, AssertFatal(ra->ra_ss!=NULL,"SearchSpace cannot be null for RA\n"); ra->coreset = get_coreset(nr_mac, scc, dl_bwp, ra->ra_ss, NR_SearchSpace__searchSpaceType_PR_common); + NR_COMMON_channels_t *cc = &nr_mac->common_channels[0]; + int ssb_index = cc->ssb_index[ra->beam_id]; ra->sched_pdcch = set_pdcch_structure(nr_mac, ra->ra_ss, ra->coreset, scc, &dl_genericParameters, - &nr_mac->type0_PDCCH_CSS_config[ra->beam_id]); + &nr_mac->type0_PDCCH_CSS_config[ssb_index]); UL_BWP->dci_format = NR_UL_DCI_FORMAT_0_0; DL_BWP->dci_format = NR_DL_DCI_FORMAT_1_0; @@ -3114,6 +3107,44 @@ void UL_tti_req_ahead_initialization(gNB_MAC_INST *gNB, int n, int CCid, frame_t } } +int get_fapi_beamforming_index(gNB_MAC_INST *mac, int ssb_idx) +{ + int beam_idx = mac->fapi_beam_index[ssb_idx]; + AssertFatal(beam_idx >= 0, "Invalid beamforming index %d\n", beam_idx); + return beam_idx; +} + +// TODO this is a placeholder for a possibly more complex function +// for now the fapi beam index is the number of SSBs transmitted before ssb_index i +void fapi_beam_index_allocation(NR_ServingCellConfigCommon_t *scc, gNB_MAC_INST *mac) +{ + int len = 0; + uint8_t* buf = NULL; + switch (scc->ssb_PositionsInBurst->present) { + case NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_shortBitmap: + len = 4; + buf = scc->ssb_PositionsInBurst->choice.shortBitmap.buf; + break; + case NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_mediumBitmap: + len = 8; + buf = scc->ssb_PositionsInBurst->choice.mediumBitmap.buf; + break; + case NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_longBitmap: + len = 64; + buf = scc->ssb_PositionsInBurst->choice.longBitmap.buf; + break; + default : + AssertFatal(false, "Invalid configuration\n"); + } + int fapi_index = 0; + for (int i = 0; i < len; ++i) { + if ((buf[i / 8] >> (7 - i % 8)) & 0x1) + mac->fapi_beam_index[i] = fapi_index++; + else + mac->fapi_beam_index[i] = -1; + } +} + static inline int get_beam_index(const NR_beam_info_t *beam_info, int frame, int slot, int beam_index, int slots_per_frame) { return ((frame * slots_per_frame + slot) / beam_info->beam_duration) % beam_info->beam_allocation_size; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index cb233eae1b..5e752696fb 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -2483,6 +2483,12 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot, n pusch_pdu->pusch_data.tb_size = sched_pusch->tb_size; pusch_pdu->pusch_data.num_cb = 0; //CBG not supported + // Beamforming + pusch_pdu->beamforming.num_prgs = 0; + pusch_pdu->beamforming.prg_size = 0; // bwp_size; + pusch_pdu->beamforming.dig_bf_interface = 1; + pusch_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = UE->UE_beam_index; + pusch_pdu->maintenance_parms_v3.ldpcBaseGraph = get_BG(sched_pusch->tb_size<<3,sched_pusch->R); // Calacualte the normalized tx_power for PHR @@ -2584,6 +2590,11 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot, n dci_pdu->CceIndex = sched_ctrl->cce_index; dci_pdu->beta_PDCCH_1_0 = 0; dci_pdu->powerControlOffsetSS = 1; + dci_pdu->precodingAndBeamforming.num_prgs = 0; + dci_pdu->precodingAndBeamforming.prg_size = 0; + dci_pdu->precodingAndBeamforming.dig_bf_interfaces = 1; + dci_pdu->precodingAndBeamforming.prgs_list[0].pm_idx = 0; + dci_pdu->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = UE->UE_beam_index; dci_pdu_rel15_t uldci_payload; memset(&uldci_payload, 0, sizeof(uldci_payload)); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 756ddbb39e..da3b612561 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -439,6 +439,8 @@ int get_mcs_from_bler(const NR_bler_options_t *bler_options, int ul_buffer_index(int frame, int slot, int scs, int size); void UL_tti_req_ahead_initialization(gNB_MAC_INST *gNB, int n, int CCid, frame_t frameP, int slotP); +void fapi_beam_index_allocation(NR_ServingCellConfigCommon_t *scc, gNB_MAC_INST *mac); +int get_fapi_beamforming_index(gNB_MAC_INST *mac, int ssb_idx); NR_beam_alloc_t beam_allocation_procedure(NR_beam_info_t *beam_info, int frame, int slot, int beam_index, int slots_per_frame); void reset_beam_status(NR_beam_info_t *beam_info, int frame, int slot, int beam_index, int slots_per_frame, bool new_beam); diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c index e8519a151a..2b23529cd2 100644 --- a/openair2/LAYER2/NR_MAC_gNB/main.c +++ b/openair2/LAYER2/NR_MAC_gNB/main.c @@ -316,7 +316,7 @@ void mac_top_init_gNB(ngran_node_t node_type, srand48(0); - // triggers also PYH initialization in case we have L1 via FAPI + // triggers also PHY initialization in case we have L1 via FAPI nr_mac_config_scc(RC.nrmac[0], scc, config); } diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 74e924564c..77c676c3a3 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -911,7 +911,7 @@ typedef struct gNB_MAC_INST_s { uint8_t min_grant_mcs; bool identity_pm; int precoding_matrix_size[NR_MAX_NB_LAYERS]; - + int fapi_beam_index[MAX_NUM_OF_SSB]; nr_mac_rrc_ul_if_t mac_rrc; f1_config_t f1_config; int16_t frame;