2020-11-26 01:25:22 -08:00
|
|
|
/**
|
2022-04-29 00:28:44 -07:00
|
|
|
* Copyright 2013-2022 Software Radio Systems Limited
|
2014-05-12 10:44:00 -07:00
|
|
|
*
|
2021-04-22 01:59:40 -07:00
|
|
|
* This file is part of srsRAN.
|
2014-05-12 10:44:00 -07:00
|
|
|
*
|
2021-04-22 01:59:40 -07:00
|
|
|
* srsRAN is free software: you can redistribute it and/or modify
|
2021-03-28 14:12:42 -07:00
|
|
|
* it under the terms of the GNU Affero General Public License as
|
|
|
|
* published by the Free Software Foundation, either version 3 of
|
|
|
|
* the License, or (at your option) any later version.
|
|
|
|
*
|
2021-04-22 01:59:40 -07:00
|
|
|
* srsRAN is distributed in the hope that it will be useful,
|
2021-03-28 14:12:42 -07:00
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU Affero General Public License for more details.
|
2014-05-12 10:44:00 -07:00
|
|
|
*
|
2021-03-28 14:12:42 -07:00
|
|
|
* A copy of the GNU Affero General Public License can be found in
|
|
|
|
* the LICENSE file in the top-level directory of this distribution
|
|
|
|
* and at http://www.gnu.org/licenses/.
|
2014-05-12 10:44:00 -07:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2021-03-19 03:45:56 -07:00
|
|
|
#include "srsran/phy/phch/ra.h"
|
|
|
|
#include "srsran/phy/common/phy_common.h"
|
|
|
|
#include "srsran/phy/utils/bit.h"
|
|
|
|
#include "srsran/phy/utils/debug.h"
|
|
|
|
#include "srsran/phy/utils/vector.h"
|
|
|
|
#include "srsran/srsran.h"
|
2019-04-23 01:53:11 -07:00
|
|
|
#include <math.h>
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <strings.h>
|
2014-05-12 10:44:00 -07:00
|
|
|
|
|
|
|
#include "tbs_tables.h"
|
|
|
|
|
2019-04-23 01:53:11 -07:00
|
|
|
/* Convert Type2 scheduling L_crb and RB_start to RIV value */
|
2021-03-19 03:45:56 -07:00
|
|
|
uint32_t srsran_ra_type2_to_riv(uint32_t L_crb, uint32_t RB_start, uint32_t nof_prb)
|
2015-04-27 09:14:28 -07:00
|
|
|
{
|
2019-04-23 01:53:11 -07:00
|
|
|
uint32_t riv;
|
|
|
|
if ((L_crb - 1) <= nof_prb / 2) {
|
|
|
|
riv = nof_prb * (L_crb - 1) + RB_start;
|
2015-05-18 12:00:47 -07:00
|
|
|
} else {
|
2019-04-23 01:53:11 -07:00
|
|
|
riv = nof_prb * (nof_prb - L_crb + 1) + nof_prb - 1 - RB_start;
|
2017-07-25 04:17:36 -07:00
|
|
|
}
|
2019-04-23 01:53:11 -07:00
|
|
|
return riv;
|
2017-07-25 04:17:36 -07:00
|
|
|
}
|
|
|
|
|
2019-04-23 01:53:11 -07:00
|
|
|
/* Convert Type2 scheduling RIV value to L_crb and RB_start values */
|
2021-03-19 03:45:56 -07:00
|
|
|
void srsran_ra_type2_from_riv(uint32_t riv, uint32_t* L_crb, uint32_t* RB_start, uint32_t nof_prb, uint32_t nof_vrb)
|
2017-09-21 03:48:09 -07:00
|
|
|
{
|
2019-04-23 01:53:11 -07:00
|
|
|
*L_crb = (uint32_t)(riv / nof_prb) + 1;
|
|
|
|
*RB_start = (uint32_t)(riv % nof_prb);
|
|
|
|
if (*L_crb > nof_vrb - *RB_start) {
|
|
|
|
*L_crb = nof_prb - (int)(riv / nof_prb) + 1;
|
|
|
|
*RB_start = nof_prb - riv % nof_prb - 1;
|
2014-06-17 02:11:41 -07:00
|
|
|
}
|
2014-05-12 10:44:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/* RBG size for type0 scheduling as in table 7.1.6.1-1 of 36.213 */
|
2021-03-19 03:45:56 -07:00
|
|
|
uint32_t srsran_ra_type0_P(uint32_t nof_prb)
|
2019-12-16 07:04:22 -08:00
|
|
|
{
|
2014-06-17 02:11:41 -07:00
|
|
|
if (nof_prb <= 10) {
|
|
|
|
return 1;
|
|
|
|
} else if (nof_prb <= 26) {
|
|
|
|
return 2;
|
|
|
|
} else if (nof_prb <= 63) {
|
|
|
|
return 3;
|
|
|
|
} else {
|
|
|
|
return 4;
|
|
|
|
}
|
2014-05-12 10:44:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Returns N_rb_type1 according to section 7.1.6.2 */
|
2021-03-19 03:45:56 -07:00
|
|
|
uint32_t srsran_ra_type1_N_rb(uint32_t nof_prb)
|
2019-12-16 07:04:22 -08:00
|
|
|
{
|
2021-03-19 03:45:56 -07:00
|
|
|
uint32_t P = srsran_ra_type0_P(nof_prb);
|
2019-12-16 07:04:22 -08:00
|
|
|
return (uint32_t)ceilf((float)nof_prb / P) - (uint32_t)ceilf(log2f((float)P)) - 1;
|
2014-05-12 10:44:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Table 6.2.3.2-1 in 36.211 */
|
2021-03-19 03:45:56 -07:00
|
|
|
uint32_t srsran_ra_type2_ngap(uint32_t nof_prb, bool ngap_is_1)
|
2019-12-16 07:04:22 -08:00
|
|
|
{
|
2014-06-17 02:11:41 -07:00
|
|
|
if (nof_prb <= 10) {
|
2014-06-17 07:32:19 -07:00
|
|
|
return nof_prb / 2;
|
2014-06-17 02:11:41 -07:00
|
|
|
} else if (nof_prb == 11) {
|
|
|
|
return 4;
|
|
|
|
} else if (nof_prb <= 19) {
|
|
|
|
return 8;
|
|
|
|
} else if (nof_prb <= 26) {
|
|
|
|
return 12;
|
|
|
|
} else if (nof_prb <= 44) {
|
|
|
|
return 18;
|
|
|
|
} else if (nof_prb <= 49) {
|
|
|
|
return 27;
|
|
|
|
} else if (nof_prb <= 63) {
|
2014-06-17 07:32:19 -07:00
|
|
|
return ngap_is_1 ? 27 : 9;
|
2014-06-17 02:11:41 -07:00
|
|
|
} else if (nof_prb <= 79) {
|
2014-06-17 07:32:19 -07:00
|
|
|
return ngap_is_1 ? 32 : 16;
|
2014-06-17 02:11:41 -07:00
|
|
|
} else {
|
2014-06-17 07:32:19 -07:00
|
|
|
return ngap_is_1 ? 48 : 16;
|
2014-06-17 02:11:41 -07:00
|
|
|
}
|
2014-05-12 10:44:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Table 7.1.6.3-1 in 36.213 */
|
2021-03-19 03:45:56 -07:00
|
|
|
uint32_t srsran_ra_type2_n_rb_step(uint32_t nof_prb)
|
2019-12-16 07:04:22 -08:00
|
|
|
{
|
2014-06-17 02:11:41 -07:00
|
|
|
if (nof_prb < 50) {
|
|
|
|
return 2;
|
|
|
|
} else {
|
|
|
|
return 4;
|
|
|
|
}
|
2014-05-12 10:44:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/* as defined in 6.2.3.2 of 36.211 */
|
2021-03-19 03:45:56 -07:00
|
|
|
uint32_t srsran_ra_type2_n_vrb_dl(uint32_t nof_prb, bool ngap_is_1)
|
2019-12-16 07:04:22 -08:00
|
|
|
{
|
2021-03-19 03:45:56 -07:00
|
|
|
uint32_t ngap = srsran_ra_type2_ngap(nof_prb, ngap_is_1);
|
2014-06-17 02:11:41 -07:00
|
|
|
if (ngap_is_1) {
|
2014-06-17 07:32:19 -07:00
|
|
|
return 2 * (ngap < (nof_prb - ngap) ? ngap : nof_prb - ngap);
|
2014-06-17 02:11:41 -07:00
|
|
|
} else {
|
2019-12-16 07:04:22 -08:00
|
|
|
return ((uint32_t)nof_prb / ngap) * 2 * ngap;
|
2014-06-17 02:11:41 -07:00
|
|
|
}
|
2014-05-12 10:44:00 -07:00
|
|
|
}
|
|
|
|
|
2015-10-30 06:42:46 -07:00
|
|
|
/* Modulation and TBS index table for PDSCH from 3GPP TS 36.213 v10.3.0 table 7.1.7.1-1 */
|
2021-03-19 03:45:56 -07:00
|
|
|
static int srsran_ra_dl_tbs_idx_from_mcs(uint32_t mcs, bool use_tbs_index_alt)
|
2019-01-17 03:42:01 -08:00
|
|
|
{
|
2020-04-10 01:27:45 -07:00
|
|
|
if (use_tbs_index_alt && mcs < 28) {
|
|
|
|
return dl_mcs_tbs_idx_table2[mcs];
|
|
|
|
} else if (!use_tbs_index_alt && mcs < 29) {
|
2019-01-17 03:42:01 -08:00
|
|
|
return dl_mcs_tbs_idx_table[mcs];
|
2015-10-30 06:42:46 -07:00
|
|
|
} else {
|
2021-03-19 03:45:56 -07:00
|
|
|
return SRSRAN_ERROR;
|
2015-10-30 06:42:46 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-19 03:45:56 -07:00
|
|
|
static int srsran_ra_ul_tbs_idx_from_mcs(uint32_t mcs)
|
2019-01-17 03:42:01 -08:00
|
|
|
{
|
|
|
|
if (mcs < 29) {
|
|
|
|
return ul_mcs_tbs_idx_table[mcs];
|
|
|
|
} else {
|
2021-03-19 03:45:56 -07:00
|
|
|
return SRSRAN_ERROR;
|
2019-01-17 03:42:01 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-19 03:45:56 -07:00
|
|
|
int srsran_ra_tbs_idx_from_mcs(uint32_t mcs, bool use_tbs_index_alt, bool is_ul)
|
2019-04-23 01:53:11 -07:00
|
|
|
{
|
2021-03-19 03:45:56 -07:00
|
|
|
return (is_ul) ? srsran_ra_ul_tbs_idx_from_mcs(mcs) : srsran_ra_dl_tbs_idx_from_mcs(mcs, use_tbs_index_alt);
|
2019-04-23 01:53:11 -07:00
|
|
|
}
|
|
|
|
|
2021-03-19 03:45:56 -07:00
|
|
|
srsran_mod_t srsran_ra_dl_mod_from_mcs(uint32_t mcs, bool use_tbs_index_alt)
|
2019-01-17 03:42:01 -08:00
|
|
|
{
|
2020-04-10 01:27:45 -07:00
|
|
|
if (use_tbs_index_alt) {
|
2020-04-14 09:57:33 -07:00
|
|
|
// 3GPP 36.213 R12 Table 7.1.7.1-1A
|
2020-04-10 01:27:45 -07:00
|
|
|
if (mcs < 5 || mcs == 28) {
|
2021-03-19 03:45:56 -07:00
|
|
|
return SRSRAN_MOD_QPSK;
|
2020-04-10 01:27:45 -07:00
|
|
|
} else if (mcs < 11 || mcs == 29) {
|
2021-03-19 03:45:56 -07:00
|
|
|
return SRSRAN_MOD_16QAM;
|
2020-04-10 01:27:45 -07:00
|
|
|
} else if (mcs < 20 || mcs == 30) {
|
2021-03-19 03:45:56 -07:00
|
|
|
return SRSRAN_MOD_64QAM;
|
2020-04-10 01:27:45 -07:00
|
|
|
} else {
|
2021-03-19 03:45:56 -07:00
|
|
|
return SRSRAN_MOD_256QAM;
|
2020-04-10 01:27:45 -07:00
|
|
|
}
|
2016-11-17 11:05:56 -08:00
|
|
|
} else {
|
2020-04-14 09:57:33 -07:00
|
|
|
// 3GPP 36.213 R12 Table 7.1.7.1-1
|
|
|
|
if (mcs < 10 || mcs == 29) {
|
2021-03-19 03:45:56 -07:00
|
|
|
return SRSRAN_MOD_QPSK;
|
2020-04-14 09:57:33 -07:00
|
|
|
} else if (mcs < 17 || mcs == 30) {
|
2021-03-19 03:45:56 -07:00
|
|
|
return SRSRAN_MOD_16QAM;
|
2020-04-10 01:27:45 -07:00
|
|
|
} else {
|
2021-03-19 03:45:56 -07:00
|
|
|
return SRSRAN_MOD_64QAM;
|
2020-04-10 01:27:45 -07:00
|
|
|
}
|
2019-06-19 08:58:01 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-19 03:45:56 -07:00
|
|
|
srsran_mod_t srsran_ra_ul_mod_from_mcs(uint32_t mcs)
|
2019-01-17 03:42:01 -08:00
|
|
|
{
|
|
|
|
/* Table 8.6.1-1 on 36.213 */
|
|
|
|
if (mcs <= 10) {
|
2021-03-19 03:45:56 -07:00
|
|
|
return SRSRAN_MOD_QPSK;
|
2019-01-17 03:42:01 -08:00
|
|
|
} else if (mcs <= 20) {
|
2021-03-19 03:45:56 -07:00
|
|
|
return SRSRAN_MOD_16QAM;
|
2019-01-17 03:42:01 -08:00
|
|
|
} else if (mcs <= 28) {
|
2021-03-19 03:45:56 -07:00
|
|
|
return SRSRAN_MOD_64QAM;
|
2019-01-17 03:42:01 -08:00
|
|
|
} else {
|
2021-03-19 03:45:56 -07:00
|
|
|
return SRSRAN_MOD_BPSK;
|
2019-01-17 03:42:01 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-19 03:45:56 -07:00
|
|
|
static int srsran_ra_dl_mcs_from_tbs_idx(uint32_t tbs_idx, bool use_tbs_index_alt)
|
2019-01-17 03:42:01 -08:00
|
|
|
{
|
2020-04-10 01:27:45 -07:00
|
|
|
if (use_tbs_index_alt) {
|
2021-03-03 08:26:06 -08:00
|
|
|
for (int mcs = 27; mcs >= 0; mcs--) {
|
|
|
|
if (tbs_idx == dl_mcs_tbs_idx_table2[mcs]) {
|
|
|
|
return mcs;
|
2020-04-10 01:27:45 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2021-03-03 08:26:06 -08:00
|
|
|
for (int mcs = 28; mcs >= 0; mcs--) {
|
|
|
|
if (tbs_idx == dl_mcs_tbs_idx_table[mcs]) {
|
|
|
|
return mcs;
|
2020-04-10 01:27:45 -07:00
|
|
|
}
|
2016-05-31 06:56:32 -07:00
|
|
|
}
|
2019-01-17 03:42:01 -08:00
|
|
|
}
|
2021-03-19 03:45:56 -07:00
|
|
|
return SRSRAN_ERROR;
|
2019-01-17 03:42:01 -08:00
|
|
|
}
|
|
|
|
|
2021-03-19 03:45:56 -07:00
|
|
|
static int srsran_ra_ul_mcs_from_tbs_idx(uint32_t tbs_idx)
|
2019-01-17 03:42:01 -08:00
|
|
|
{
|
2021-03-03 08:26:06 -08:00
|
|
|
// Note: go in descent order to find max mcs possible
|
|
|
|
for (int mcs = 28; mcs >= 0; mcs--) {
|
|
|
|
if (tbs_idx == ul_mcs_tbs_idx_table[mcs]) {
|
|
|
|
return mcs;
|
2019-01-17 03:42:01 -08:00
|
|
|
}
|
|
|
|
}
|
2021-03-19 03:45:56 -07:00
|
|
|
return SRSRAN_ERROR;
|
2016-05-31 06:56:32 -07:00
|
|
|
}
|
|
|
|
|
2021-03-19 03:45:56 -07:00
|
|
|
int srsran_ra_mcs_from_tbs_idx(uint32_t tbs_idx, bool use_tbs_index_alt, bool is_ul)
|
2019-04-23 01:53:11 -07:00
|
|
|
{
|
2021-03-19 03:45:56 -07:00
|
|
|
return is_ul ? srsran_ra_ul_mcs_from_tbs_idx(tbs_idx) : srsran_ra_dl_mcs_from_tbs_idx(tbs_idx, use_tbs_index_alt);
|
2019-04-23 01:53:11 -07:00
|
|
|
}
|
|
|
|
|
2015-04-27 09:14:28 -07:00
|
|
|
/* Table 7.1.7.2.1-1: Transport block size table on 36.213 */
|
2021-03-19 03:45:56 -07:00
|
|
|
int srsran_ra_tbs_from_idx(uint32_t tbs_idx, uint32_t n_prb)
|
2019-04-23 01:53:11 -07:00
|
|
|
{
|
2021-03-19 03:45:56 -07:00
|
|
|
if (tbs_idx < SRSRAN_RA_NOF_TBS_IDX && n_prb > 0 && n_prb <= SRSRAN_MAX_PRB) {
|
2014-06-17 07:32:19 -07:00
|
|
|
return tbs_table[tbs_idx][n_prb - 1];
|
2014-06-17 02:11:41 -07:00
|
|
|
} else {
|
2021-03-19 03:45:56 -07:00
|
|
|
return SRSRAN_ERROR;
|
2014-06-17 02:11:41 -07:00
|
|
|
}
|
2014-05-12 10:44:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Returns lowest nearest index of TBS value in table 7.1.7.2 on 36.213
|
|
|
|
* or -1 if the TBS value is not within the valid TBS values
|
|
|
|
*/
|
2021-03-03 08:26:06 -08:00
|
|
|
/*
|
|
|
|
* Returns upper bound (exclusive) of TBS index interval whose TBS value encompasses the provided TBS
|
|
|
|
* \remark taken from table 7.1.7.2 on 36.213
|
|
|
|
* @return upper bound of TBS index (0..27), -2 if bad arguments
|
|
|
|
*/
|
2021-03-19 03:45:56 -07:00
|
|
|
int srsran_ra_tbs_to_table_idx(uint32_t tbs, uint32_t n_prb, uint32_t max_tbs_idx)
|
2019-12-16 07:04:22 -08:00
|
|
|
{
|
2021-03-19 03:45:56 -07:00
|
|
|
if (n_prb == 0 || n_prb > SRSRAN_MAX_PRB) {
|
|
|
|
return SRSRAN_ERROR_INVALID_INPUTS;
|
2021-03-03 08:26:06 -08:00
|
|
|
}
|
|
|
|
if (tbs < tbs_table[0][n_prb - 1]) {
|
|
|
|
return 0;
|
|
|
|
}
|
2021-03-06 09:00:44 -08:00
|
|
|
for (int tbs_idx = max_tbs_idx; tbs_idx >= 0; tbs_idx--) {
|
|
|
|
if (tbs_table[tbs_idx][n_prb - 1] <= tbs) {
|
|
|
|
return tbs_idx + 1;
|
2014-06-17 02:11:41 -07:00
|
|
|
}
|
|
|
|
}
|
2021-03-19 03:45:56 -07:00
|
|
|
return SRSRAN_ERROR;
|
2014-05-12 10:44:00 -07:00
|
|
|
}
|