Enable PHR reporting for NR UE
This commit is contained in:
committed by
Robert Schmidt
parent
bd721c3bdb
commit
c7c1cb2dbf
@@ -1879,7 +1879,21 @@ static void configure_maccellgroup(NR_UE_MAC_INST_t *mac, const NR_MAC_CellGroup
|
||||
}
|
||||
}
|
||||
if (mcg->phr_Config) {
|
||||
// TODO configuration when PHR is implemented
|
||||
nr_phr_info_t *phr_info = &si->phr_info;
|
||||
phr_info->is_configured = mcg->phr_Config->choice.setup != NULL;
|
||||
if (phr_info->is_configured) {
|
||||
int slots_per_subframe = nr_slots_per_frame[scs] / 10;
|
||||
struct NR_PHR_Config *config = mcg->phr_Config->choice.setup;
|
||||
AssertFatal(config->multiplePHR == 0, "mulitplePHR not supported");
|
||||
phr_info->PathlossChange_db = config->phr_Tx_PowerFactorChange;
|
||||
const int periodic_timer_sf_enum_to_sf[] = {10, 20, 50, 100, 200, 500, 1000, UINT_MAX};
|
||||
int periodic_timer_sf = periodic_timer_sf_enum_to_sf[config->phr_PeriodicTimer];
|
||||
nr_timer_setup(&phr_info->periodicPHR_Timer, periodic_timer_sf * slots_per_subframe, 1);
|
||||
const int prohibit_timer_sf_enum_to_sf[] = {0, 10, 20, 50, 100, 200, 500, 1000};
|
||||
int prohibit_timer_sf = prohibit_timer_sf_enum_to_sf[config->phr_ProhibitTimer];
|
||||
nr_timer_setup(&phr_info->prohibitPHR_Timer, prohibit_timer_sf * slots_per_subframe, 1);
|
||||
phr_info->phr_reporting = (1 << phr_cause_phr_config);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -172,6 +172,12 @@
|
||||
UE_STATE(UE_CONNECTED) \
|
||||
UE_STATE(UE_DETACHING)
|
||||
|
||||
typedef enum {
|
||||
phr_cause_prohibit_timer = 0,
|
||||
phr_cause_periodic_timer,
|
||||
phr_cause_phr_config,
|
||||
} NR_UE_PHR_Reporting_cause_t;
|
||||
|
||||
/*!\brief UE layer 2 status */
|
||||
typedef enum {
|
||||
#define UE_STATE(state) state,
|
||||
@@ -222,6 +228,24 @@ typedef struct {
|
||||
uint32_t maxTransmissions;
|
||||
} nr_sr_info_t;
|
||||
|
||||
typedef struct {
|
||||
bool is_configured;
|
||||
///timer before triggering a periodic PHR
|
||||
NR_timer_t periodicPHR_Timer;
|
||||
///timer before triggering a prohibit PHR
|
||||
NR_timer_t prohibitPHR_Timer;
|
||||
///DL Pathloss change value
|
||||
uint16_t PathlossLastValue;
|
||||
///number of subframe before triggering a periodic PHR
|
||||
int16_t periodicPHR_SF;
|
||||
///number of subframe before triggering a prohibit PHR
|
||||
int16_t prohibitPHR_SF;
|
||||
///DL Pathloss Change in db
|
||||
uint16_t PathlossChange_db;
|
||||
int phr_reporting;
|
||||
bool was_mac_reset;
|
||||
} nr_phr_info_t;
|
||||
|
||||
// LTE structure, might need to be adapted for NR
|
||||
typedef struct {
|
||||
// lcs scheduling info
|
||||
@@ -240,18 +264,8 @@ typedef struct {
|
||||
NR_timer_t retxBSR_Timer;
|
||||
/// periodicBSR-Timer
|
||||
NR_timer_t periodicBSR_Timer;
|
||||
///timer before triggering a periodic PHR
|
||||
uint16_t periodicPHR_Timer;
|
||||
///timer before triggering a prohibit PHR
|
||||
uint16_t prohibitPHR_Timer;
|
||||
///DL Pathloss change value
|
||||
uint16_t PathlossChange;
|
||||
///number of subframe before triggering a periodic PHR
|
||||
int16_t periodicPHR_SF;
|
||||
///number of subframe before triggering a prohibit PHR
|
||||
int16_t prohibitPHR_SF;
|
||||
///DL Pathloss Change in db
|
||||
uint16_t PathlossChange_db;
|
||||
|
||||
nr_phr_info_t phr_info;
|
||||
} NR_UE_SCHEDULING_INFO;
|
||||
|
||||
typedef enum {
|
||||
@@ -560,9 +574,6 @@ typedef struct NR_UE_MAC_INST_s {
|
||||
|
||||
NR_UE_SCHEDULING_INFO scheduling_info;
|
||||
|
||||
/// PHR
|
||||
uint8_t PHR_reporting_active;
|
||||
|
||||
int dmrs_TypeA_Position;
|
||||
int p_Max;
|
||||
int p_Max_alt;
|
||||
|
||||
@@ -173,7 +173,7 @@ void nr_ue_process_mac_pdu(NR_UE_MAC_INST_t *mac,nr_downlink_indication_t *dl_in
|
||||
|
||||
int nr_write_ce_ulsch_pdu(uint8_t *mac_ce,
|
||||
NR_UE_MAC_INST_t *mac,
|
||||
uint8_t power_headroom, // todo: NR_POWER_HEADROOM_CMD *power_headroom,
|
||||
NR_SINGLE_ENTRY_PHR_MAC_CE *power_headroom,
|
||||
uint16_t *crnti,
|
||||
NR_BSR_SHORT *truncated_bsr,
|
||||
NR_BSR_SHORT *short_bsr,
|
||||
@@ -193,7 +193,9 @@ uint8_t nr_ue_get_sdu(NR_UE_MAC_INST_t *mac,
|
||||
sub_frame_t subframe,
|
||||
uint8_t gNB_index,
|
||||
uint8_t *ulsch_buffer,
|
||||
uint32_t buflen);
|
||||
uint32_t buflen,
|
||||
int16_t tx_power,
|
||||
int16_t P_CMAX);
|
||||
|
||||
void set_harq_status(NR_UE_MAC_INST_t *mac,
|
||||
uint8_t pucch_id,
|
||||
|
||||
@@ -118,8 +118,10 @@ void nr_ue_mac_default_configs(NR_UE_MAC_INST_t *mac)
|
||||
nr_timer_setup(&mac->scheduling_info.retxBSR_Timer, 80 * subframes_per_slot, 1); // 1 slot update rate
|
||||
nr_timer_setup(&mac->scheduling_info.periodicBSR_Timer, 10 * subframes_per_slot, 1); // 1 slot update rate
|
||||
|
||||
mac->scheduling_info.periodicPHR_Timer = NR_PHR_Config__phr_PeriodicTimer_sf10;
|
||||
mac->scheduling_info.prohibitPHR_Timer = NR_PHR_Config__phr_ProhibitTimer_sf10;
|
||||
mac->scheduling_info.phr_info.is_configured = true;
|
||||
mac->scheduling_info.phr_info.PathlossChange_db = 1;
|
||||
nr_timer_setup(&mac->scheduling_info.phr_info.periodicPHR_Timer, 10 * subframes_per_slot, 1);
|
||||
nr_timer_setup(&mac->scheduling_info.phr_info.prohibitPHR_Timer, 10 * subframes_per_slot, 1);
|
||||
}
|
||||
|
||||
void nr_ue_send_synch_request(NR_UE_MAC_INST_t *mac, module_id_t module_id, int cc_id, const fapi_nr_synch_request_t *sync_req)
|
||||
@@ -229,7 +231,8 @@ void reset_mac_inst(NR_UE_MAC_INST_t *nr_mac)
|
||||
nr_mac->scheduling_info.BSR_reporting_active = NR_BSR_TRIGGER_NONE;
|
||||
|
||||
// cancel any triggered Power Headroom Reporting procedure
|
||||
// TODO PHR not implemented yet
|
||||
nr_mac->scheduling_info.phr_info.phr_reporting = 0;
|
||||
nr_mac->scheduling_info.phr_info.was_mac_reset = true;
|
||||
|
||||
// flush the soft buffers for all DL HARQ processes
|
||||
for (int k = 0; k < NR_MAX_HARQ_PROCESSES; k++)
|
||||
|
||||
@@ -3668,30 +3668,28 @@ void nr_ue_process_mac_pdu(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_i
|
||||
*/
|
||||
int nr_write_ce_ulsch_pdu(uint8_t *mac_ce,
|
||||
NR_UE_MAC_INST_t *mac,
|
||||
uint8_t power_headroom, // todo: NR_POWER_HEADROOM_CMD *power_headroom,
|
||||
NR_SINGLE_ENTRY_PHR_MAC_CE *power_headroom,
|
||||
uint16_t *crnti,
|
||||
NR_BSR_SHORT *truncated_bsr,
|
||||
NR_BSR_SHORT *short_bsr,
|
||||
NR_BSR_LONG *long_bsr)
|
||||
{
|
||||
int mac_ce_len = 0;
|
||||
uint8_t mac_ce_size = 0;
|
||||
uint8_t *pdu = mac_ce;
|
||||
if (power_headroom) {
|
||||
|
||||
// MAC CE fixed subheader
|
||||
((NR_MAC_SUBHEADER_FIXED *) mac_ce)->R = 0;
|
||||
((NR_MAC_SUBHEADER_FIXED *) mac_ce)->LCID = UL_SCH_LCID_SINGLE_ENTRY_PHR;
|
||||
mac_ce++;
|
||||
|
||||
// PHR MAC CE (1 octet)
|
||||
((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->PH = power_headroom;
|
||||
((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->PH = power_headroom->PH;
|
||||
((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->R1 = 0;
|
||||
((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->PCMAX = 0; // todo
|
||||
((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->PCMAX = power_headroom->PCMAX;
|
||||
((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->R2 = 0;
|
||||
|
||||
// update pointer and length
|
||||
mac_ce_size = sizeof(NR_SINGLE_ENTRY_PHR_MAC_CE);
|
||||
int mac_ce_size = sizeof(NR_SINGLE_ENTRY_PHR_MAC_CE);
|
||||
mac_ce += mac_ce_size;
|
||||
mac_ce_len += mac_ce_size + sizeof(NR_MAC_SUBHEADER_FIXED);
|
||||
LOG_D(NR_MAC, "[UE] Generating ULSCH PDU : power_headroom pdu %p mac_ce %p b\n",
|
||||
@@ -3710,7 +3708,7 @@ int nr_write_ce_ulsch_pdu(uint8_t *mac_ce,
|
||||
memcpy(mac_ce, crnti, sizeof(*crnti));
|
||||
|
||||
// update pointer and length
|
||||
mac_ce_size = sizeof(uint16_t);
|
||||
int mac_ce_size = sizeof(uint16_t);
|
||||
mac_ce += mac_ce_size;
|
||||
mac_ce_len += mac_ce_size + sizeof(NR_MAC_SUBHEADER_FIXED);
|
||||
}
|
||||
@@ -3727,7 +3725,7 @@ int nr_write_ce_ulsch_pdu(uint8_t *mac_ce,
|
||||
((NR_BSR_SHORT_TRUNCATED *) mac_ce)-> LcgID = truncated_bsr->LcgID;;
|
||||
|
||||
// update pointer and length
|
||||
mac_ce_size = sizeof(NR_BSR_SHORT_TRUNCATED);
|
||||
int mac_ce_size = sizeof(NR_BSR_SHORT_TRUNCATED);
|
||||
mac_ce += mac_ce_size;
|
||||
mac_ce_len += mac_ce_size + sizeof(NR_MAC_SUBHEADER_FIXED);
|
||||
LOG_D(NR_MAC, "[UE] Generating ULSCH PDU : truncated_bsr Buffer_size %d LcgID %d pdu %p mac_ce %p\n",
|
||||
@@ -3745,7 +3743,7 @@ int nr_write_ce_ulsch_pdu(uint8_t *mac_ce,
|
||||
((NR_BSR_SHORT *) mac_ce)->LcgID = short_bsr->LcgID;
|
||||
|
||||
// update pointer and length
|
||||
mac_ce_size = sizeof(NR_BSR_SHORT);
|
||||
int mac_ce_size = sizeof(NR_BSR_SHORT);
|
||||
mac_ce += mac_ce_size;
|
||||
mac_ce_len += mac_ce_size + sizeof(NR_MAC_SUBHEADER_FIXED);
|
||||
LOG_D(NR_MAC, "[UE] Generating ULSCH PDU : short_bsr Buffer_size %d LcgID %d pdu %p mac_ce %p\n",
|
||||
@@ -3812,7 +3810,7 @@ int nr_write_ce_ulsch_pdu(uint8_t *mac_ce,
|
||||
((NR_BSR_LONG *) mac_ce)->LcgID7 = 1;
|
||||
*Buffer_size_ptr++ = long_bsr->Buffer_size7;
|
||||
}
|
||||
((NR_MAC_SUBHEADER_SHORT *) mac_pdu_subheader_ptr)->L = mac_ce_size = (uint8_t*) Buffer_size_ptr - (uint8_t*) mac_ce;
|
||||
int mac_ce_size = ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_subheader_ptr)->L = (uint8_t*) Buffer_size_ptr - (uint8_t*) mac_ce;
|
||||
LOG_D(NR_MAC, "[UE] Generating ULSCH PDU : long_bsr size %d Lcgbit 0x%02x Buffer_size %d %d %d %d %d %d %d %d\n", mac_ce_size, *((uint8_t*) mac_ce),
|
||||
((NR_BSR_LONG *) mac_ce)->Buffer_size0, ((NR_BSR_LONG *) mac_ce)->Buffer_size1, ((NR_BSR_LONG *) mac_ce)->Buffer_size2, ((NR_BSR_LONG *) mac_ce)->Buffer_size3,
|
||||
((NR_BSR_LONG *) mac_ce)->Buffer_size4, ((NR_BSR_LONG *) mac_ce)->Buffer_size5, ((NR_BSR_LONG *) mac_ce)->Buffer_size6, ((NR_BSR_LONG *) mac_ce)->Buffer_size7);
|
||||
|
||||
@@ -64,6 +64,12 @@
|
||||
|
||||
static void nr_ue_prach_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, sub_frame_t slotP);
|
||||
static void schedule_ta_command(fapi_nr_dl_config_request_t *dl_config, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment);
|
||||
static void nr_ue_fill_phr(NR_UE_MAC_INST_t *mac,
|
||||
NR_SINGLE_ENTRY_PHR_MAC_CE *phr,
|
||||
float P_CMAX,
|
||||
float tx_power,
|
||||
frame_t frameP,
|
||||
sub_frame_t subframe);
|
||||
|
||||
void clear_ul_config_request(NR_UE_MAC_INST_t *mac, int scs)
|
||||
{
|
||||
@@ -176,6 +182,21 @@ void update_mac_timers(NR_UE_MAC_INST_t *mac)
|
||||
AssertFatal(!nr_timer_tick(&mac->scheduling_info.lc_sched_info[i].Bj_timer),
|
||||
"Bj timer for LCID %d expired! That should never happen\n",
|
||||
i);
|
||||
|
||||
nr_phr_info_t *phr_info = &mac->scheduling_info.phr_info;
|
||||
if (phr_info->is_configured) {
|
||||
bool prohibit_expired = nr_timer_tick(&phr_info->prohibitPHR_Timer);
|
||||
if (prohibit_expired) {
|
||||
int16_t pathloss = compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm);
|
||||
if (abs(pathloss - phr_info->PathlossLastValue) > phr_info->PathlossChange_db) {
|
||||
phr_info->phr_reporting |= (1 << phr_cause_prohibit_timer);
|
||||
}
|
||||
}
|
||||
bool periodic_expired = nr_timer_tick(&phr_info->periodicPHR_Timer);
|
||||
if (periodic_expired) {
|
||||
phr_info->phr_reporting |= (1 << phr_cause_periodic_timer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void remove_ul_config_last_item(fapi_nr_ul_config_request_pdu_t *pdu)
|
||||
@@ -942,6 +963,16 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 38.321 5.4.6
|
||||
// if it is the first UL resource allocated for a new transmission since the last MAC reset:
|
||||
// 2> start phr-PeriodicTimer;
|
||||
if (mac->scheduling_info.phr_info.is_configured) {
|
||||
if (mac->scheduling_info.phr_info.was_mac_reset && pusch_config_pdu->pusch_data.new_data_indicator) {
|
||||
mac->scheduling_info.phr_info.was_mac_reset = false;
|
||||
nr_timer_start(&mac->scheduling_info.phr_info.periodicPHR_Timer);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1185,7 +1216,6 @@ static bool nr_ue_periodic_srs_scheduling(NR_UE_MAC_INST_t *mac, frame_t frame,
|
||||
// Performs :
|
||||
// 1. TODO: Call RRC for link status return to PHY
|
||||
// 2. TODO: Perform SR/BSR procedures for scheduling feedback
|
||||
// 3. TODO: Perform PHR procedures
|
||||
void nr_ue_dl_scheduler(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_info)
|
||||
{
|
||||
frame_t rx_frame = dl_info->frame;
|
||||
@@ -1422,10 +1452,24 @@ void nr_ue_ul_scheduler(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info)
|
||||
if (ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator
|
||||
&& (mac->state == UE_CONNECTED || (ra->ra_state == nrRA_WAIT_RAR && ra->cfra))) {
|
||||
// Getting IP traffic to be transmitted
|
||||
nr_ue_get_sdu(mac, cc_id, frame_tx, slot_tx, gNB_index, ulsch_input_buffer, TBS_bytes);
|
||||
ulcfg_pdu->pusch_config_pdu.tx_request_body.fapiTxPdu = ulsch_input_buffer;
|
||||
ulcfg_pdu->pusch_config_pdu.tx_request_body.pdu_length = TBS_bytes;
|
||||
number_of_pdus++;
|
||||
int tx_power = ulcfg_pdu->pusch_config_pdu.tx_power;
|
||||
int P_CMAX = nr_get_Pcmax(mac->p_Max,
|
||||
mac->nr_band,
|
||||
mac->frame_type,
|
||||
mac->frequency_range,
|
||||
mac->current_UL_BWP->channel_bandwidth,
|
||||
ulcfg_pdu->pusch_config_pdu.qam_mod_order,
|
||||
false,
|
||||
mac->current_UL_BWP->scs,
|
||||
mac->current_UL_BWP->BWPSize,
|
||||
ulcfg_pdu->pusch_config_pdu.transform_precoding,
|
||||
ulcfg_pdu->pusch_config_pdu.rb_size,
|
||||
ulcfg_pdu->pusch_config_pdu.rb_start);
|
||||
|
||||
nr_ue_get_sdu(mac, cc_id, frame_tx, slot_tx, gNB_index, ulsch_input_buffer, TBS_bytes, tx_power, P_CMAX);
|
||||
ulcfg_pdu->pusch_config_pdu.tx_request_body.fapiTxPdu = ulsch_input_buffer;
|
||||
ulcfg_pdu->pusch_config_pdu.tx_request_body.pdu_length = TBS_bytes;
|
||||
number_of_pdus++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2735,6 +2779,7 @@ typedef struct {
|
||||
NR_BSR_SHORT *bsr_s;
|
||||
NR_BSR_LONG *bsr_l;
|
||||
NR_BSR_SHORT *bsr_t;
|
||||
NR_SINGLE_ENTRY_PHR_MAC_CE* phr;
|
||||
//NR_POWER_HEADROOM_CMD *phr_pr;
|
||||
int tot_mac_ce_len;
|
||||
uint8_t total_mac_pdu_header_len;
|
||||
@@ -2758,12 +2803,13 @@ static int nr_ue_get_sdu_mac_ce_pre(NR_UE_MAC_INST_t *mac,
|
||||
uint8_t gNB_index,
|
||||
uint8_t *ulsch_buffer,
|
||||
uint32_t buflen,
|
||||
int16_t tx_power,
|
||||
int16_t P_CMAX,
|
||||
NR_UE_MAC_CE_INFO *mac_ce_p)
|
||||
{
|
||||
int num_lcg_id_with_data = 0;
|
||||
// Preparing the MAC CEs sub-PDUs and get the total size
|
||||
mac_ce_p->bsr_header_len = 0;
|
||||
mac_ce_p->phr_header_len = 0; //sizeof(SCH_SUBHEADER_FIXED);
|
||||
int lcg_id = 0;
|
||||
while (lcg_id != NR_INVALID_LCGID) {
|
||||
if (mac->scheduling_info.lcg_sched_info[lcg_id].BSR_bytes) {
|
||||
@@ -2794,8 +2840,23 @@ static int nr_ue_get_sdu_mac_ce_pre(NR_UE_MAC_INST_t *mac,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mac_ce_p->bsr_len = mac_ce_p->bsr_ce_len + mac_ce_p->bsr_header_len;
|
||||
|
||||
|
||||
nr_phr_info_t *phr_info = &mac->scheduling_info.phr_info;
|
||||
mac_ce_p->phr_header_len = 0;
|
||||
mac_ce_p->phr_ce_len = 0;
|
||||
if (phr_info->is_configured && phr_info->phr_reporting > 0) {
|
||||
if (buflen >= (mac_ce_p->bsr_len + sizeof(NR_MAC_SUBHEADER_FIXED) + sizeof(NR_SINGLE_ENTRY_PHR_MAC_CE))) {
|
||||
if (mac->scheduling_info.phr_info.phr_reporting) {
|
||||
mac_ce_p->phr_header_len = sizeof(NR_MAC_SUBHEADER_FIXED);
|
||||
mac_ce_p->phr_ce_len = sizeof(NR_SINGLE_ENTRY_PHR_MAC_CE);
|
||||
nr_ue_fill_phr(mac, mac_ce_p->phr, P_CMAX, tx_power, frameP, subframe);
|
||||
}
|
||||
}
|
||||
}
|
||||
mac_ce_p->phr_len = mac_ce_p->phr_header_len + mac_ce_p->phr_ce_len;
|
||||
|
||||
return (mac_ce_p->bsr_len + mac_ce_p->phr_len);
|
||||
}
|
||||
|
||||
@@ -3234,7 +3295,9 @@ uint8_t nr_ue_get_sdu(NR_UE_MAC_INST_t *mac,
|
||||
slot_t slot,
|
||||
uint8_t gNB_index,
|
||||
uint8_t *ulsch_buffer,
|
||||
uint32_t buflen)
|
||||
uint32_t buflen,
|
||||
int16_t tx_power,
|
||||
int16_t P_CMAX)
|
||||
{
|
||||
NR_UE_MAC_CE_INFO mac_ce_info;
|
||||
NR_UE_MAC_CE_INFO *mac_ce_p=&mac_ce_info;
|
||||
@@ -3253,8 +3316,9 @@ uint8_t nr_ue_get_sdu(NR_UE_MAC_INST_t *mac,
|
||||
mac_ce_p->bsr_s = &bsr_short;
|
||||
mac_ce_p->bsr_l = &bsr_long;
|
||||
mac_ce_p->bsr_t = &bsr_truncated;
|
||||
//NR_POWER_HEADROOM_CMD phr;
|
||||
//mac_ce_p->phr_p = &phr;
|
||||
|
||||
NR_SINGLE_ENTRY_PHR_MAC_CE phr;
|
||||
mac_ce_p->phr = &phr;
|
||||
|
||||
//int highest_priority = 16;
|
||||
const uint8_t sh_size = sizeof(NR_MAC_SUBHEADER_LONG);
|
||||
@@ -3273,7 +3337,7 @@ uint8_t nr_ue_get_sdu(NR_UE_MAC_INST_t *mac,
|
||||
// because as per standard(TS38.321), all equal priority channels should be served equally
|
||||
|
||||
// nr_ue_get_sdu_mac_ce_pre updates all mac_ce related header field related to length
|
||||
mac_ce_p->tot_mac_ce_len = nr_ue_get_sdu_mac_ce_pre(mac, CC_id, frame, slot, gNB_index, ulsch_buffer, buflen, mac_ce_p);
|
||||
mac_ce_p->tot_mac_ce_len = nr_ue_get_sdu_mac_ce_pre(mac, CC_id, frame, slot, gNB_index, ulsch_buffer, buflen, tx_power, P_CMAX, mac_ce_p);
|
||||
mac_ce_p->total_mac_pdu_header_len = mac_ce_p->tot_mac_ce_len;
|
||||
|
||||
LOG_D(NR_MAC, "[UE %d] [%d.%d] process UL transport block at with size TBS = %d bytes \n", mac->ue_id, frame, slot, buflen);
|
||||
@@ -3373,9 +3437,8 @@ uint8_t nr_ue_get_sdu(NR_UE_MAC_INST_t *mac,
|
||||
nr_ue_get_sdu_mac_ce_post(mac, frame, slot, ulsch_buffer, buflen, mac_ce_p);
|
||||
|
||||
if (mac_ce_p->tot_mac_ce_len > 0) {
|
||||
|
||||
LOG_D(NR_MAC, "In %s copying %d bytes of MAC CEs to the UL PDU \n", __FUNCTION__, mac_ce_p->tot_mac_ce_len);
|
||||
int size = nr_write_ce_ulsch_pdu(pdu, mac, 0, NULL, mac_ce_p->bsr_t, mac_ce_p->bsr_s, mac_ce_p->bsr_l);
|
||||
int size = nr_write_ce_ulsch_pdu(pdu, mac, mac_ce_p->phr_ce_len ? mac_ce_p->phr : NULL, 0, mac_ce_p->bsr_t, mac_ce_p->bsr_s, mac_ce_p->bsr_l);
|
||||
if (size != mac_ce_p->tot_mac_ce_len)
|
||||
LOG_E(NR_MAC, "MAC CE size computed by nr_write_ce_ulsch_pdu is %d while the one assumed before is %d\n", size, mac_ce_p->tot_mac_ce_len);
|
||||
pdu += (unsigned char) mac_ce_p->tot_mac_ce_len;
|
||||
@@ -3436,3 +3499,42 @@ static void schedule_ta_command(fapi_nr_dl_config_request_t *dl_config, NR_UL_TI
|
||||
dl_config->number_pdus += 1;
|
||||
ul_time_alignment->ta_apply = no_ta;
|
||||
}
|
||||
|
||||
static void nr_ue_fill_phr(NR_UE_MAC_INST_t *mac,
|
||||
NR_SINGLE_ENTRY_PHR_MAC_CE *phr,
|
||||
float P_CMAX,
|
||||
float tx_power,
|
||||
frame_t frameP,
|
||||
sub_frame_t subframe)
|
||||
{
|
||||
nr_phr_info_t *phr_info = &mac->scheduling_info.phr_info;
|
||||
// Value mapping according to 38.133 10.1.18.1
|
||||
const int PC_MAX_00 = -29;
|
||||
phr->PCMAX = max(0, (int)P_CMAX - PC_MAX_00) & 0x3f;
|
||||
// Value mapping according to 38.133 10.1.17.1.1
|
||||
const int POWER_HEADROOM_55 = 22;
|
||||
int headroom = P_CMAX - tx_power;
|
||||
if (headroom < POWER_HEADROOM_55) {
|
||||
const int POWER_HEADROOM_0 = -32;
|
||||
phr->PH = max(0, headroom - POWER_HEADROOM_0);
|
||||
} else {
|
||||
phr->PH = min(0x3f, 55 + (headroom - POWER_HEADROOM_55) / 2);
|
||||
}
|
||||
|
||||
LOG_D(NR_MAC,
|
||||
"PHR Reporting sfn.subframe %d.%d reason = %d, P_CMAX = %d (%5.2f dBm), headrom = %d (%d dB) tx_power = %5.2f dBm\n",
|
||||
frameP,
|
||||
subframe,
|
||||
phr_info->phr_reporting,
|
||||
phr->PCMAX,
|
||||
P_CMAX,
|
||||
phr->PH,
|
||||
headroom,
|
||||
tx_power);
|
||||
|
||||
phr_info->PathlossLastValue = compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm);
|
||||
// Restart both timers according to 38.321
|
||||
nr_timer_start(&phr_info->periodicPHR_Timer);
|
||||
nr_timer_start(&phr_info->prohibitPHR_Timer);
|
||||
phr_info->phr_reporting = 0;
|
||||
}
|
||||
|
||||
@@ -331,8 +331,16 @@ static int nr_process_mac_pdu(instance_t module_idP,
|
||||
sched_ctrl->ph0 = PH;
|
||||
/* 38.133 Table10.1.18.1-1 */
|
||||
sched_ctrl->pcmax = PCMAX - 29;
|
||||
LOG_D(NR_MAC, "SINGLE ENTRY PHR R1 %d PH %d (%d dB) R2 %d PCMAX %d (%d dBm)\n",
|
||||
phr->R1, PH, sched_ctrl->ph, phr->R2, PCMAX, sched_ctrl->pcmax);
|
||||
LOG_D(NR_MAC,
|
||||
"SINGLE ENTRY PHR %d.%d R1 %d PH %d (%d dB) R2 %d PCMAX %d (%d dBm)\n",
|
||||
frameP,
|
||||
slot,
|
||||
phr->R1,
|
||||
PH,
|
||||
sched_ctrl->ph,
|
||||
phr->R2,
|
||||
PCMAX,
|
||||
sched_ctrl->pcmax);
|
||||
break;
|
||||
|
||||
case UL_SCH_LCID_MULTI_ENTRY_PHR_1_OCT:
|
||||
|
||||
Reference in New Issue
Block a user