|
|
|
@ -477,6 +477,7 @@ int srslte_pdsch_cfg_mimo(srslte_pdsch_cfg_t *cfg, srslte_cell_t cell, srslte_ra
|
|
|
|
|
cfg->sf_idx = sf_idx;
|
|
|
|
|
memcpy(cfg->rv, rvidx, sizeof(uint32_t) * SRSLTE_MAX_CODEWORDS);
|
|
|
|
|
cfg->mimo_type = mimo_type;
|
|
|
|
|
cfg->tb_cw_swap = grant->tb_cw_swap;
|
|
|
|
|
|
|
|
|
|
/* Check and configure PDSCH transmission modes */
|
|
|
|
|
switch(mimo_type) {
|
|
|
|
@ -543,19 +544,19 @@ static srslte_sequence_t *get_user_sequence(srslte_pdsch_t *q, uint16_t rnti,
|
|
|
|
|
|
|
|
|
|
static int srslte_pdsch_codeword_encode(srslte_pdsch_t *q, srslte_pdsch_cfg_t *cfg,
|
|
|
|
|
srslte_softbuffer_tx_t *softbuffer, uint16_t rnti, uint8_t *data,
|
|
|
|
|
uint32_t codeword_idx) {
|
|
|
|
|
srslte_ra_nbits_t *nbits = &cfg->nbits[codeword_idx];
|
|
|
|
|
srslte_ra_mcs_t *mcs = &cfg->grant.mcs[codeword_idx];
|
|
|
|
|
uint32_t rv = cfg->rv[codeword_idx];
|
|
|
|
|
uint32_t codeword_idx, uint32_t tb_idx) {
|
|
|
|
|
srslte_ra_nbits_t *nbits = &cfg->nbits[tb_idx];
|
|
|
|
|
srslte_ra_mcs_t *mcs = &cfg->grant.mcs[tb_idx];
|
|
|
|
|
uint32_t rv = cfg->rv[tb_idx];
|
|
|
|
|
|
|
|
|
|
if (nbits->nof_bits) {
|
|
|
|
|
INFO("Encoding PDSCH SF: %d (TB %d), Mod %s, NofBits: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n",
|
|
|
|
|
cfg->sf_idx, codeword_idx, srslte_mod_string(mcs->mod), mcs->tbs,
|
|
|
|
|
INFO("Encoding PDSCH SF: %d (TB%d -> CW%d), Mod %s, NofBits: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n",
|
|
|
|
|
cfg->sf_idx, tb_idx, codeword_idx, srslte_mod_string(mcs->mod), mcs->tbs,
|
|
|
|
|
nbits->nof_re, nbits->nof_bits, rv);
|
|
|
|
|
|
|
|
|
|
/* Channel coding */
|
|
|
|
|
if (srslte_dlsch_encode2(&q->dl_sch, cfg, softbuffer, data, q->e[codeword_idx], codeword_idx)) {
|
|
|
|
|
ERROR("Error encoding TB %d", codeword_idx);
|
|
|
|
|
if (srslte_dlsch_encode2(&q->dl_sch, cfg, softbuffer, data, q->e[codeword_idx], tb_idx)) {
|
|
|
|
|
ERROR("Error encoding (TB%d -> CW%d)", tb_idx, codeword_idx);
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -577,15 +578,15 @@ static int srslte_pdsch_codeword_encode(srslte_pdsch_t *q, srslte_pdsch_cfg_t *c
|
|
|
|
|
|
|
|
|
|
static int srslte_pdsch_codeword_decode(srslte_pdsch_t *q, srslte_pdsch_cfg_t *cfg,
|
|
|
|
|
srslte_softbuffer_rx_t *softbuffer, uint16_t rnti, uint8_t *data,
|
|
|
|
|
uint32_t codeword_idx, bool *ack) {
|
|
|
|
|
srslte_ra_nbits_t *nbits = &cfg->nbits[codeword_idx];
|
|
|
|
|
srslte_ra_mcs_t *mcs = &cfg->grant.mcs[codeword_idx];
|
|
|
|
|
uint32_t rv = cfg->rv[codeword_idx];
|
|
|
|
|
uint32_t codeword_idx, uint32_t tb_idx, bool *ack) {
|
|
|
|
|
srslte_ra_nbits_t *nbits = &cfg->nbits[tb_idx];
|
|
|
|
|
srslte_ra_mcs_t *mcs = &cfg->grant.mcs[tb_idx];
|
|
|
|
|
uint32_t rv = cfg->rv[tb_idx];
|
|
|
|
|
int ret = SRSLTE_ERROR_INVALID_INPUTS;
|
|
|
|
|
|
|
|
|
|
if (softbuffer && data && ack) {
|
|
|
|
|
INFO("Decoding PDSCH SF: %d (TB %d), Mod %s, NofBits: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n",
|
|
|
|
|
cfg->sf_idx, codeword_idx, srslte_mod_string(mcs->mod), mcs->tbs,
|
|
|
|
|
INFO("Decoding PDSCH SF: %d (CW%d -> TB%d), Mod %s, NofBits: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n",
|
|
|
|
|
cfg->sf_idx, codeword_idx, tb_idx, srslte_mod_string(mcs->mod), mcs->tbs,
|
|
|
|
|
nbits->nof_re, nbits->nof_bits, rv);
|
|
|
|
|
|
|
|
|
|
/* demodulate symbols
|
|
|
|
@ -601,7 +602,7 @@ static int srslte_pdsch_codeword_decode(srslte_pdsch_t *q, srslte_pdsch_cfg_t *c
|
|
|
|
|
srslte_scrambling_s_offset(seq, q->e[codeword_idx], 0, nbits->nof_bits);
|
|
|
|
|
|
|
|
|
|
/* Return */
|
|
|
|
|
ret = srslte_dlsch_decode2(&q->dl_sch, cfg, softbuffer, q->e[codeword_idx], data, codeword_idx);
|
|
|
|
|
ret = srslte_dlsch_decode2(&q->dl_sch, cfg, softbuffer, q->e[codeword_idx], data, tb_idx);
|
|
|
|
|
|
|
|
|
|
q->last_nof_iterations[codeword_idx] = srslte_sch_last_noi(&q->dl_sch);
|
|
|
|
|
|
|
|
|
@ -690,17 +691,23 @@ int srslte_pdsch_decode(srslte_pdsch_t *q,
|
|
|
|
|
srslte_layerdemap_type(x, q->d, cfg->nof_layers, nof_tb,
|
|
|
|
|
nof_symbols[0], nof_symbols, cfg->mimo_type);
|
|
|
|
|
}
|
|
|
|
|
// Codeword decoding
|
|
|
|
|
for (uint32_t tb = 0; tb < SRSLTE_MAX_CODEWORDS; tb ++) {
|
|
|
|
|
|
|
|
|
|
/* Codeword decoding: Implementation of 3GPP 36.212 Table 5.3.3.1.5-1 and Table 5.3.3.1.5-2 */
|
|
|
|
|
uint32_t cw_idx = (nof_tb == SRSLTE_MAX_TB && cfg->tb_cw_swap) ? 1 : 0;
|
|
|
|
|
for (uint32_t tb_idx = 0; tb_idx < SRSLTE_MAX_TB; tb_idx++) {
|
|
|
|
|
/* Decode only if transport block is enabled and the default ACK is not true */
|
|
|
|
|
if (cfg->grant.tb_en[tb] && !acks[tb]) {
|
|
|
|
|
int ret = srslte_pdsch_codeword_decode(q, cfg, softbuffers[tb], rnti, data[tb], tb, &acks[tb]);
|
|
|
|
|
if (cfg->grant.tb_en[tb_idx]) {
|
|
|
|
|
if (!acks[tb_idx]) {
|
|
|
|
|
int ret = srslte_pdsch_codeword_decode(q, cfg, softbuffers[tb_idx], rnti, data[tb_idx], cw_idx, tb_idx, &acks[tb_idx]);
|
|
|
|
|
|
|
|
|
|
/* Check if there has been any execution error */
|
|
|
|
|
if (ret) {
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cw_idx = (cw_idx + 1) % SRSLTE_MAX_CODEWORDS;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pdsch_decode_debug(q, cfg, sf_symbols, ce);
|
|
|
|
@ -772,20 +779,23 @@ int srslte_pdsch_encode(srslte_pdsch_t *q,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* If both transport block size is zero return error */
|
|
|
|
|
if (cfg->grant.mcs[0].tbs == 0) {
|
|
|
|
|
if (!nof_tb) {
|
|
|
|
|
return SRSLTE_ERROR_INVALID_INPUTS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (cfg->nbits[0].nof_re > q->max_re) {
|
|
|
|
|
if (cfg->nbits[0].nof_re > q->max_re || cfg->nbits[1].nof_re > q->max_re) {
|
|
|
|
|
fprintf(stderr,
|
|
|
|
|
"Error too many RE per subframe (%d). PDSCH configured for %d RE (%d PRB)\n",
|
|
|
|
|
cfg->nbits[0].nof_re, q->max_re, q->cell.nof_prb);
|
|
|
|
|
return SRSLTE_ERROR_INVALID_INPUTS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (uint32_t tb = 0; tb < SRSLTE_MAX_CODEWORDS; tb ++) {
|
|
|
|
|
if (cfg->grant.tb_en[tb]) {
|
|
|
|
|
ret |= srslte_pdsch_codeword_encode(q, cfg, softbuffers[tb], rnti, data[tb], tb);
|
|
|
|
|
/* Implementation of 3GPP 36.212 Table 5.3.3.1.5-1 and Table 5.3.3.1.5-2 */
|
|
|
|
|
uint32_t cw_idx = (nof_tb == SRSLTE_MAX_TB && cfg->tb_cw_swap) ? 1 : 0;
|
|
|
|
|
for (uint32_t tb_idx = 0; tb_idx < SRSLTE_MAX_TB; tb_idx++) {
|
|
|
|
|
if (cfg->grant.tb_en[tb_idx]) {
|
|
|
|
|
ret |= srslte_pdsch_codeword_encode(q, cfg, softbuffers[tb_idx], rnti, data[tb_idx], cw_idx, tb_idx);
|
|
|
|
|
cw_idx = (cw_idx + 1) % SRSLTE_MAX_CODEWORDS;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|