update
This commit is contained in:
@@ -462,92 +462,117 @@ static inline void do_txdataF(c16_t **txdataF,
|
||||
int start_sc,
|
||||
int txdataF_offset_per_symbol)
|
||||
{
|
||||
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
|
||||
int rb = 0;
|
||||
uint16_t subCarrier = start_sc;
|
||||
const nfapi_nr_tx_precoding_and_beamforming_t *pb = &rel15->precodingAndBeamforming;
|
||||
while (rb < rel15->rbSize) {
|
||||
// get pmi info
|
||||
const int pmi = (pb->prg_size > 0) ? (pb->prgs_list[(int)rb / pb->prg_size].pm_idx) : 0;
|
||||
const int pmi2 = (rb < (rel15->rbSize - 1) && pb->prg_size > 0) ? (pb->prgs_list[(int)(rb + 1) / pb->prg_size].pm_idx) : -1;
|
||||
const int pmi3 = (rb < (rel15->rbSize - 2) && pb->prg_size > 0) ? (pb->prgs_list[(int)(rb + 2) / pb->prg_size].pm_idx) : -1;
|
||||
const int pmi4 = (rb < (rel15->rbSize - 3) && pb->prg_size > 0) ? (pb->prgs_list[(int)(rb + 3) / pb->prg_size].pm_idx) : -1;
|
||||
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
|
||||
int rb = 0;
|
||||
uint16_t subCarrier = start_sc;
|
||||
const nfapi_nr_tx_precoding_and_beamforming_t *pb = &rel15->precodingAndBeamforming;
|
||||
|
||||
// If pmi of next RB and pmi of current RB are the same, we do 2 RB in a row
|
||||
// if pmi differs, or current rb is the end (rel15->rbSize - 1), than we do 1 RB in a row
|
||||
int rb_step0 = pmi == pmi2 ? 2 : 1;
|
||||
const int rb_step = rb_step0==2 && pmi3==pmi && pmi4==pmi ? 4 : rb_step0;
|
||||
const int re_cnt = NR_NB_SC_PER_RB * rb_step;
|
||||
if (pmi == 0) { // unitary Precoding
|
||||
if (subCarrier + re_cnt <= symbol_sz) { // RB does not cross DC
|
||||
if (ant < rel15->nrOfLayers)
|
||||
memcpy(&txdataF[ant][txdataF_offset_per_symbol + subCarrier],
|
||||
&txdataF_precoding[ant][subCarrier],
|
||||
re_cnt * sizeof(**txdataF));
|
||||
else
|
||||
memset(&txdataF[ant][txdataF_offset_per_symbol + subCarrier], 0, re_cnt * sizeof(**txdataF));
|
||||
} else { // RB does cross DC
|
||||
const int neg_length = symbol_sz - subCarrier;
|
||||
const int pos_length = re_cnt - neg_length;
|
||||
if (ant < rel15->nrOfLayers) {
|
||||
memcpy(&txdataF[ant][txdataF_offset_per_symbol + subCarrier],
|
||||
&txdataF_precoding[ant][subCarrier],
|
||||
neg_length * sizeof(**txdataF));
|
||||
memcpy(&txdataF[ant][txdataF_offset_per_symbol], &txdataF_precoding[ant], pos_length * sizeof(**txdataF));
|
||||
// Compute which layer this antenna carries under identity precoding.
|
||||
// Standard identity maps layer N → antenna N, but when antennas are muted
|
||||
// we must remap layers to active antennas. Otherwise layer data sent to a
|
||||
// muted antenna is lost (RU blanks it) while active antennas sit idle.
|
||||
// E.g. mask=0x0D (ant 1 muted, 3 layers): ant0→L0, ant2→L1, ant3→L2.
|
||||
int identity_layer = -1;
|
||||
{
|
||||
const nr_antenna_state_t *ast = &gNB->antenna_state;
|
||||
int active_count = nr_get_active_tx_antenna_count(ast);
|
||||
if (active_count > 0 && active_count < frame_parms->nb_antennas_tx) {
|
||||
if (nr_is_tx_antenna_active(ast, ant)) {
|
||||
identity_layer = 0;
|
||||
for (int a = 0; a < ant; a++)
|
||||
if (nr_is_tx_antenna_active(ast, a))
|
||||
identity_layer++;
|
||||
if (identity_layer >= rel15->nrOfLayers)
|
||||
identity_layer = -1;
|
||||
}
|
||||
} else {
|
||||
memset(&txdataF[ant][txdataF_offset_per_symbol + subCarrier], 0, neg_length * sizeof(**txdataF));
|
||||
memset(&txdataF[ant][txdataF_offset_per_symbol], 0, pos_length * sizeof(**txdataF));
|
||||
// No muting: standard identity (layer N = antenna N)
|
||||
identity_layer = (ant < rel15->nrOfLayers) ? ant : -1;
|
||||
}
|
||||
}
|
||||
subCarrier += re_cnt;
|
||||
if (subCarrier >= symbol_sz) {
|
||||
subCarrier -= symbol_sz;
|
||||
}
|
||||
} else { // non-unitary Precoding
|
||||
AssertFatal(frame_parms->nb_antennas_tx > 1, "No precoding can be done with a single antenna port\n");
|
||||
// get the precoding matrix weights:
|
||||
nfapi_nr_pm_pdu_t *pmi_pdu = &gNB->gNB_config.pmi_list.pmi_pdu[pmi - 1]; // pmi 0 is identity matrix
|
||||
AssertFatal(pmi == pmi_pdu->pm_idx, "PMI %d doesn't match to the one in precoding matrix %d\n", pmi, pmi_pdu->pm_idx);
|
||||
AssertFatal(ant < pmi_pdu->num_ant_ports,
|
||||
"Antenna port index %d exceeds precoding matrix AP size %d\n",
|
||||
ant,
|
||||
pmi_pdu->num_ant_ports);
|
||||
AssertFatal(rel15->nrOfLayers == pmi_pdu->numLayers,
|
||||
"Number of layers %d doesn't match to the one in precoding matrix %d\n",
|
||||
rel15->nrOfLayers,
|
||||
pmi_pdu->numLayers);
|
||||
if ((subCarrier + re_cnt) < symbol_sz) { // within ofdm_symbol_size, use SIMDe
|
||||
nr_layer_precoder_simd(rel15->nrOfLayers,
|
||||
symbol_sz,
|
||||
txdataF_precoding,
|
||||
ant,
|
||||
pmi_pdu,
|
||||
subCarrier,
|
||||
re_cnt,
|
||||
&txdataF[ant][txdataF_offset_per_symbol]);
|
||||
subCarrier += re_cnt;
|
||||
} else { // crossing ofdm_symbol_size, use simple arithmetic operations
|
||||
for (int i = 0; i < re_cnt; i++) {
|
||||
txdataF[ant][txdataF_offset_per_symbol + subCarrier] =
|
||||
nr_layer_precoder_cm(rel15->nrOfLayers, symbol_sz, txdataF_precoding, ant, pmi_pdu, subCarrier);
|
||||
#ifdef DEBUG_DLSCH_MAPPING
|
||||
printf("antenna %d\t l %d \t subCarrier %d \t txdataF: %d %d\n",
|
||||
ant,
|
||||
l_symbol,
|
||||
subCarrier,
|
||||
txdataF[ant][l_symbol * symbol_sz + subCarrier + txdataF_offset].r,
|
||||
txdataF[ant][l_symbol * symbol_sz + subCarrier + txdataF_offset].i);
|
||||
#endif
|
||||
if (++subCarrier >= symbol_sz) {
|
||||
subCarrier -= symbol_sz;
|
||||
}
|
||||
}
|
||||
} // else{ // crossing ofdm_symbol_size, use simple arithmetic operations
|
||||
} // else { // non-unitary Precoding
|
||||
}
|
||||
|
||||
rb += rb_step;
|
||||
} // RB loop: while(rb < rel15->rbSize)
|
||||
while (rb < rel15->rbSize) {
|
||||
// get pmi info
|
||||
const int pmi = (pb->prg_size > 0) ? (pb->prgs_list[(int)rb / pb->prg_size].pm_idx) : 0;
|
||||
const int pmi2 = (rb < (rel15->rbSize - 1) && pb->prg_size > 0) ? (pb->prgs_list[(int)(rb + 1) / pb->prg_size].pm_idx) : -1;
|
||||
const int pmi3 = (rb < (rel15->rbSize - 2) && pb->prg_size > 0) ? (pb->prgs_list[(int)(rb + 2) / pb->prg_size].pm_idx) : -1;
|
||||
const int pmi4 = (rb < (rel15->rbSize - 3) && pb->prg_size > 0) ? (pb->prgs_list[(int)(rb + 3) / pb->prg_size].pm_idx) : -1;
|
||||
|
||||
// If pmi of next RB and pmi of current RB are the same, we do 2 RB in a row
|
||||
// if pmi differs, or current rb is the end (rel15->rbSize - 1), than we do 1 RB in a row
|
||||
int rb_step0 = pmi == pmi2 ? 2 : 1;
|
||||
const int rb_step = rb_step0==2 && pmi3==pmi && pmi4==pmi ? 4 : rb_step0;
|
||||
const int re_cnt = NR_NB_SC_PER_RB * rb_step;
|
||||
if (pmi == 0) { // unitary Precoding
|
||||
if (subCarrier + re_cnt <= symbol_sz) { // RB does not cross DC
|
||||
if (identity_layer >= 0)
|
||||
memcpy(&txdataF[ant][txdataF_offset_per_symbol + subCarrier],
|
||||
&txdataF_precoding[identity_layer][subCarrier],
|
||||
re_cnt * sizeof(**txdataF));
|
||||
else
|
||||
memset(&txdataF[ant][txdataF_offset_per_symbol + subCarrier], 0, re_cnt * sizeof(**txdataF));
|
||||
} else { // RB does cross DC
|
||||
const int neg_length = symbol_sz - subCarrier;
|
||||
const int pos_length = re_cnt - neg_length;
|
||||
if (identity_layer >= 0) {
|
||||
memcpy(&txdataF[ant][txdataF_offset_per_symbol + subCarrier],
|
||||
&txdataF_precoding[identity_layer][subCarrier],
|
||||
neg_length * sizeof(**txdataF));
|
||||
memcpy(&txdataF[ant][txdataF_offset_per_symbol], &txdataF_precoding[identity_layer], pos_length * sizeof(**txdataF));
|
||||
} else {
|
||||
memset(&txdataF[ant][txdataF_offset_per_symbol + subCarrier], 0, neg_length * sizeof(**txdataF));
|
||||
memset(&txdataF[ant][txdataF_offset_per_symbol], 0, pos_length * sizeof(**txdataF));
|
||||
}
|
||||
}
|
||||
subCarrier += re_cnt;
|
||||
if (subCarrier >= symbol_sz) {
|
||||
subCarrier -= symbol_sz;
|
||||
}
|
||||
} else { // non-unitary Precoding
|
||||
AssertFatal(frame_parms->nb_antennas_tx > 1, "No precoding can be done with a single antenna port\n");
|
||||
// get the precoding matrix weights:
|
||||
nfapi_nr_pm_pdu_t *pmi_pdu = &gNB->gNB_config.pmi_list.pmi_pdu[pmi - 1]; // pmi 0 is identity matrix
|
||||
AssertFatal(pmi == pmi_pdu->pm_idx, "PMI %d doesn't match to the one in precoding matrix %d\n", pmi, pmi_pdu->pm_idx);
|
||||
AssertFatal(ant < pmi_pdu->num_ant_ports,
|
||||
"Antenna port index %d exceeds precoding matrix AP size %d\n",
|
||||
ant,
|
||||
pmi_pdu->num_ant_ports);
|
||||
AssertFatal(rel15->nrOfLayers == pmi_pdu->numLayers,
|
||||
"Number of layers %d doesn't match to the one in precoding matrix %d\n",
|
||||
rel15->nrOfLayers,
|
||||
pmi_pdu->numLayers);
|
||||
if ((subCarrier + re_cnt) < symbol_sz) { // within ofdm_symbol_size, use SIMDe
|
||||
nr_layer_precoder_simd(rel15->nrOfLayers,
|
||||
symbol_sz,
|
||||
txdataF_precoding,
|
||||
ant,
|
||||
pmi_pdu,
|
||||
subCarrier,
|
||||
re_cnt,
|
||||
&txdataF[ant][txdataF_offset_per_symbol]);
|
||||
subCarrier += re_cnt;
|
||||
} else { // crossing ofdm_symbol_size, use simple arithmetic operations
|
||||
for (int i = 0; i < re_cnt; i++) {
|
||||
txdataF[ant][txdataF_offset_per_symbol + subCarrier] =
|
||||
nr_layer_precoder_cm(rel15->nrOfLayers, symbol_sz, txdataF_precoding, ant, pmi_pdu, subCarrier);
|
||||
#ifdef DEBUG_DLSCH_MAPPING
|
||||
printf("antenna %d\t l %d \t subCarrier %d \t txdataF: %d %d\n",
|
||||
ant,
|
||||
l_symbol,
|
||||
subCarrier,
|
||||
txdataF[ant][l_symbol * symbol_sz + subCarrier + txdataF_offset].r,
|
||||
txdataF[ant][l_symbol * symbol_sz + subCarrier + txdataF_offset].i);
|
||||
#endif
|
||||
if (++subCarrier >= symbol_sz) {
|
||||
subCarrier -= symbol_sz;
|
||||
}
|
||||
}
|
||||
} // else{ // crossing ofdm_symbol_size, use simple arithmetic operations
|
||||
} // else { // non-unitary Precoding
|
||||
rb += rb_step;
|
||||
} // RB loop: while(rb < rel15->rbSize)
|
||||
}
|
||||
|
||||
static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSCH_t *dlsch, int slot)
|
||||
{
|
||||
const int16_t amp = gNB->TX_AMP;
|
||||
|
||||
@@ -264,25 +264,25 @@ void nr_feptx(void *arg)
|
||||
|
||||
// If there is no digital beamforming we just need to copy the data to RU
|
||||
if (ru->config.dbt_config.num_dig_beams == 0 || ru->gNB_list[0]->common_vars.analog_bf) {
|
||||
// Check antenna muting state for energy saving
|
||||
const nr_antenna_state_t *ant_state = &ru->gNB_list[0]->antenna_state;
|
||||
bool is_active = nr_is_tx_antenna_active(ant_state, aa);
|
||||
if (!is_active) {
|
||||
// Antenna is muted - zero out the buffer (transmission blanking)
|
||||
memset((void*)&ru->common.txdataF_BF[tx_idx][txdataF_BF_offset], 0, numSamples * sizeof(int32_t));
|
||||
if (startSymbol == 0) {
|
||||
LOG_I(PHY, "[ANTENNA_MUTE] TX ant %d muted (mask=0x%02X, num_tx=%d), blanking slot %d\n",
|
||||
aa, nr_get_tx_antenna_bitmask(ant_state), ant_state->num_tx_antennas, slot);
|
||||
// Check antenna muting state for energy saving
|
||||
const nr_antenna_state_t *ant_state = &ru->gNB_list[0]->antenna_state;
|
||||
bool is_active = nr_is_tx_antenna_active(ant_state, aa);
|
||||
if (!is_active) {
|
||||
// Antenna is muted - zero out the buffer (transmission blanking)
|
||||
memset((void*)&ru->common.txdataF_BF[tx_idx][txdataF_BF_offset], 0, numSamples * sizeof(int32_t));
|
||||
/* if (startSymbol == 0) { */
|
||||
/* LOG_I(PHY, "[ANTENNA_MUTE] TX ant %d muted (mask=0x%02X, num_tx=%d), blanking slot %d\n", */
|
||||
/* aa, nr_get_tx_antenna_bitmask(ant_state), ant_state->num_tx_antennas, slot); */
|
||||
/* } */
|
||||
} else {
|
||||
// Antenna is active - copy data normally
|
||||
memcpy((void*)&ru->common.txdataF_BF[tx_idx][txdataF_BF_offset],
|
||||
(void*)&ru->gNB_list[0]->common_vars.txdataF[bb][aa][txdataF_offset],
|
||||
numSamples * sizeof(int32_t));
|
||||
}
|
||||
} else {
|
||||
// Antenna is active - copy data normally
|
||||
memcpy((void*)&ru->common.txdataF_BF[tx_idx][txdataF_BF_offset],
|
||||
(void*)&ru->gNB_list[0]->common_vars.txdataF[bb][aa][txdataF_offset],
|
||||
numSamples * sizeof(int32_t));
|
||||
}
|
||||
}
|
||||
else {
|
||||
AssertFatal(false, "This needs to be fixed by using appropriate beams from config\n");
|
||||
AssertFatal(false, "This needs to be fixed by using appropriate beams from config\n");
|
||||
}
|
||||
|
||||
/* const c16_t *dst = (const c16_t *)&ru->common.txdataF_BF[tx_idx][txdataF_BF_offset]; */
|
||||
|
||||
@@ -108,7 +108,10 @@ bool read_pdcp_sm(void* data)
|
||||
}
|
||||
num_ues++;
|
||||
|
||||
AssertFatal(num_ues < MAX_MOBILES_PER_GNB, "cannot have more UEs than global UE number maximum\n");
|
||||
if (num_ues >= MAX_MOBILES_PER_GNB) {
|
||||
LOG_W(PDCP, "num_ues %zu >= MAX_MOBILES_PER_GNB %d, skipping remaining UEs\n", num_ues, MAX_MOBILES_PER_GNB);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined (NGRAN_GNB_CUUP)
|
||||
|
||||
@@ -178,7 +178,7 @@ static void capture_sst_sd(test_cond_value_t* test_cond_value, uint8_t *sst, uin
|
||||
*sd = malloc(sizeof(uint32_t));
|
||||
**sd = buf[1] << 16 | buf[2] << 8 | buf[3];
|
||||
}
|
||||
printf("[E2 AGENT][E2SM-KPM] Condition NSSAI (%d, %x).\n", *sst, (*sd) ? **sd : 0xffffff);
|
||||
/* printf("[E2 AGENT][E2SM-KPM] Condition NSSAI (%d, %x).\n", *sst, (*sd) ? **sd : 0xffffff); */
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -226,7 +226,10 @@ static arr_ue_id_t filter_ues_by_s_nssai_in_cu(const test_info_lst_t test_info)
|
||||
break;
|
||||
}
|
||||
}
|
||||
AssertFatal(arr_ue_id.sz < MAX_MOBILES_PER_GNB, "cannot have more UEs than global UE number maximum\n");
|
||||
if (arr_ue_id.sz >= MAX_MOBILES_PER_GNB) {
|
||||
LOG_W(NR_MAC, "arr_ue_id.sz %zu >= MAX_MOBILES_PER_GNB %d, skipping remaining UEs\n", arr_ue_id.sz, MAX_MOBILES_PER_GNB);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(sd); // if NULL, nothing happens
|
||||
@@ -319,7 +322,10 @@ static arr_ue_id_t filter_ues_by_s_nssai_in_du_or_monolithic(const test_info_lst
|
||||
break;
|
||||
}
|
||||
}
|
||||
AssertFatal(arr_ue_id.sz < MAX_MOBILES_PER_GNB, "cannot have more UEs than global UE number maximum\n");
|
||||
if (arr_ue_id.sz >= MAX_MOBILES_PER_GNB) {
|
||||
LOG_W(NR_MAC, "arr_ue_id.sz %zu >= MAX_MOBILES_PER_GNB %d, skipping remaining UEs\n", arr_ue_id.sz, MAX_MOBILES_PER_GNB);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
node_stats[1].mac_stats.dl.total_prb_aggregate = mac->mac_stats.dl.total_prb_aggregate;
|
||||
|
||||
@@ -3898,8 +3898,10 @@ bool nr_mac_ue_is_active(const NR_UE_info_t *ue)
|
||||
return true;
|
||||
}
|
||||
|
||||
#define UL_FAILURE_REQ_GRACE 10000
|
||||
#define UL_FAILURE_TIMEOUT 30000
|
||||
/* #define UL_FAILURE_REQ_GRACE 10000 */
|
||||
/* #define UL_FAILURE_TIMEOUT 30000 */
|
||||
#define UL_FAILURE_REQ_GRACE 2000
|
||||
#define UL_FAILURE_TIMEOUT 2500
|
||||
void nr_mac_trigger_ul_failure(NR_UE_sched_ctrl_t *sched_ctrl, NR_SubcarrierSpacing_t subcarrier_spacing)
|
||||
{
|
||||
if (sched_ctrl->ul_failure) {
|
||||
|
||||
Reference in New Issue
Block a user