Commit 7e82854b authored by francescomani's avatar francescomani

improvements to set beam index via FAPI message

use of number of SSBs transmitted before current one as fapi index, creation of a mapping vector from SSB to fapi index
parent 2a9a038d
......@@ -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
......
......@@ -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)) {
......
......@@ -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 (slot<slots_per_hf)
n_hf=0;
else
n_hf=1;
uint8_t ssb_index = ssb_pdu.ssb_pdu_rel15.SsbBlockIndex;
LOG_D(PHY,"common_signal_procedures: frame %d, slot %d ssb index %d\n", frame, slot, ssb_index);
......@@ -70,6 +59,7 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame,int slot, nfapi_nr
// for FR1 offsetToPointA and k_SSB are expressed in terms of 15 kHz SCS
// for FR2 offsetToPointA is expressed in terms of 60 kHz SCS and k_SSB expressed in terms of the subcarrier spacing provided
// by the higher-layer parameter subCarrierSpacingCommon
nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_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;j<fp->symbols_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; 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));
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; i<fp->Lmax; 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; aa<cfg->carrier_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],
......
......@@ -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;
......
......@@ -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
......
......@@ -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;
}
......
......@@ -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;
}
......
......@@ -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);
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",
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,"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; i<L_max; i++) {
for (int i = 0; i < L_max; i++) {
NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config = &gNB_mac->type0_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
}
......@@ -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;
......
......@@ -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");
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;
......
......@@ -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));
......
......@@ -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);
......
......@@ -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);
}
......
......@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment