diff --git a/lib/include/srsran/phy/phch/cqi.h b/lib/include/srsran/phy/phch/cqi.h index 3ae569e30..2bab78dfc 100644 --- a/lib/include/srsran/phy/phch/cqi.h +++ b/lib/include/srsran/phy/phch/cqi.h @@ -146,11 +146,18 @@ srsran_cqi_value_tostring(srsran_cqi_cfg_t* cfg, srsran_cqi_value_t* value, char SRSRAN_API bool srsran_cqi_periodic_send(const srsran_cqi_report_cfg_t* periodic_cfg, uint32_t tti, srsran_frame_type_t frame_type); +SRSRAN_API bool srsran_cqi_periodic_is_subband(const srsran_cqi_report_cfg_t* cfg, + uint32_t tti, + uint32_t nof_prb, + srsran_frame_type_t frame_type); + SRSRAN_API bool srsran_cqi_periodic_ri_send(const srsran_cqi_report_cfg_t* periodic_cfg, uint32_t tti, srsran_frame_type_t frame_type); SRSRAN_API int srsran_cqi_hl_get_no_subbands(int nof_prb); +SRSRAN_API int srsran_cqi_hl_get_L(int nof_prb); + SRSRAN_API uint8_t srsran_cqi_from_snr(float snr); SRSRAN_API float srsran_cqi_to_coderate(uint32_t cqi, bool use_alt_table); diff --git a/lib/src/phy/enb/enb_dl.c b/lib/src/phy/enb/enb_dl.c index c9b240b2f..5c079aab8 100644 --- a/lib/src/phy/enb/enb_dl.c +++ b/lib/src/phy/enb/enb_dl.c @@ -441,7 +441,15 @@ bool srsran_enb_dl_gen_cqi_periodic(const srsran_cell_t* cell, cqi_cfg->ri_len = srsran_ri_nof_bits(cell); cqi_enabled = true; } else if (srsran_cqi_periodic_send(&dl_cfg->cqi_report, tti, cell->frame_type)) { - cqi_cfg->type = SRSRAN_CQI_TYPE_WIDEBAND; + if (dl_cfg->cqi_report.format_is_subband && + srsran_cqi_periodic_is_subband(&dl_cfg->cqi_report, tti, cell->nof_prb, cell->frame_type)) { + // 36.213 table 7.2.2-1, periodic CQI supports UE-selected only + cqi_cfg->type = SRSRAN_CQI_TYPE_SUBBAND_UE; + cqi_cfg->L = srsran_cqi_hl_get_L(cell->nof_prb); + cqi_cfg->subband_label_2_bits = cqi_cfg->L > 1; + } else { + cqi_cfg->type = SRSRAN_CQI_TYPE_WIDEBAND; + } if (dl_cfg->tm == SRSRAN_TM4) { cqi_cfg->pmi_present = true; cqi_cfg->rank_is_not_one = last_ri > 0; diff --git a/lib/src/phy/phch/cqi.c b/lib/src/phy/phch/cqi.c index 374e50238..d7ef51d34 100644 --- a/lib/src/phy/phch/cqi.c +++ b/lib/src/phy/phch/cqi.c @@ -444,7 +444,7 @@ static bool cqi_get_N_tdd(uint32_t I_cqi_pmi, uint32_t* N_p, uint32_t* N_offset) return true; } -static bool cqi_send(uint32_t I_cqi_pmi, uint32_t tti, bool is_fdd) +static bool cqi_send(uint32_t I_cqi_pmi, uint32_t tti, bool is_fdd, uint32_t H) { uint32_t N_p = 0; @@ -461,7 +461,7 @@ static bool cqi_send(uint32_t I_cqi_pmi, uint32_t tti, bool is_fdd) } if (N_p) { - if ((tti - N_offset) % N_p == 0) { + if ((tti - N_offset) % (H * N_p) == 0) { return true; } } @@ -517,6 +517,51 @@ static bool ri_send(uint32_t I_cqi_pmi, uint32_t I_ri, uint32_t tti, bool is_fdd return false; } +/* Returns the subband size for higher layer-configured subband feedback, + * i.e., the number of RBs per subband as a function of the cell bandwidth + * (Table 7.2.1-3 in TS 36.213) + */ +static int cqi_hl_get_subband_size(int nof_prb) +{ + if (nof_prb < 7) { + return 0; + } else if (nof_prb <= 26) { + return 4; + } else if (nof_prb <= 63) { + return 6; + } else if (nof_prb <= 110) { + return 8; + } else { + return -1; + } +} + +/* Returns the bandwidth parts (J) + * (Table 7.2.2-2 in TS 36.213) + */ +static int cqi_hl_get_bwp_J(int nof_prb) +{ + if (nof_prb < 7) { + return 0; + } else if (nof_prb <= 26) { + return 4; + } else if (nof_prb <= 63) { + return 6; + } else if (nof_prb <= 110) { + return 8; + } else { + return -1; + } +} + +/* Returns the number of bits to index a bandwidth part (L) + * L = ceil(log2(nof_prb/k/J)) + */ +int srsran_cqi_hl_get_L(int nof_prb) +{ + return (int)ceil((float)nof_prb / cqi_hl_get_subband_size(nof_prb) / cqi_hl_get_bwp_J(nof_prb)); +} + bool srsran_cqi_periodic_ri_send(const srsran_cqi_report_cfg_t* cfg, uint32_t tti, srsran_frame_type_t frame_type) { return cfg->periodic_configured && cfg->ri_idx_present && @@ -525,7 +570,20 @@ bool srsran_cqi_periodic_ri_send(const srsran_cqi_report_cfg_t* cfg, uint32_t tt bool srsran_cqi_periodic_send(const srsran_cqi_report_cfg_t* cfg, uint32_t tti, srsran_frame_type_t frame_type) { - return cfg->periodic_configured && cqi_send(cfg->pmi_idx, tti, frame_type == SRSRAN_FDD); + return cfg->periodic_configured && cqi_send(cfg->pmi_idx, tti, frame_type == SRSRAN_FDD, 1); +} + +bool srsran_cqi_periodic_is_subband(const srsran_cqi_report_cfg_t* cfg, + uint32_t tti, + uint32_t nof_prb, + srsran_frame_type_t frame_type) +{ + uint32_t K = cfg->subband_wideband_ratio; + uint32_t J = cqi_hl_get_bwp_J(nof_prb); + uint32_t H = J * K + 1; + + // A periodic report is subband if it's a CQI opportunity and is not wideband + return srsran_cqi_periodic_send(cfg, tti, frame_type) && !cqi_send(cfg->pmi_idx, tti, frame_type == SRSRAN_FDD, H); } // CQI-to-Spectral Efficiency: 36.213 Table 7.2.3-1 @@ -592,25 +650,6 @@ uint8_t srsran_cqi_from_snr(float snr) return 0; } -/* Returns the subband size for higher layer-configured subband feedback, - * i.e., the number of RBs per subband as a function of the cell bandwidth - * (Table 7.2.1-3 in TS 36.213) - */ -static int cqi_hl_get_subband_size(int nof_prb) -{ - if (nof_prb < 7) { - return 0; - } else if (nof_prb <= 26) { - return 4; - } else if (nof_prb <= 63) { - return 6; - } else if (nof_prb <= 110) { - return 8; - } else { - return -1; - } -} - /* Returns the number of subbands to be reported in CQI measurements as * defined in clause 7.2 in TS 36.213, i.e., the N parameter */