Assign TFI to complete TRX, not just one TS

This is required, since we may change slot allocation. In case of a
change, we do not want to be unable to change, if the same TFI on one of
the other slots is already in use by a different TBF (having same TFI, but
on different slot).
This commit is contained in:
Andreas Eversberg 2012-08-07 17:06:08 +02:00
parent 07e97cf8a5
commit adb2f18538
4 changed files with 39 additions and 69 deletions

View File

@ -120,9 +120,9 @@ int tfi_alloc(enum gprs_rlcmac_tbf_direction dir, uint8_t *_trx, uint8_t *_ts,
LOGP(DRLCMAC, LOGL_DEBUG, "Searching for first unallocated TFI: "
"TRX=%d first TS=%d\n", trx, ts);
if (dir == GPRS_RLCMAC_UL_TBF)
tbfp = pdch->ul_tbf;
tbfp = bts->trx[trx].ul_tbf;
else
tbfp = pdch->dl_tbf;
tbfp = bts->trx[trx].dl_tbf;
for (tfi = 0; tfi < 32; tfi++) {
if (!tbfp[tfi])
break;
@ -163,19 +163,19 @@ static inline int8_t find_free_usf(struct gprs_rlcmac_pdch *pdch, uint8_t ts)
}
/* lookup TBF Entity (by TFI) */
struct gprs_rlcmac_tbf *tbf_by_tfi(uint8_t tfi, uint8_t trx, uint8_t ts,
struct gprs_rlcmac_tbf *tbf_by_tfi(uint8_t tfi, uint8_t trx,
enum gprs_rlcmac_tbf_direction dir)
{
struct gprs_rlcmac_tbf *tbf;
struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts;
if (tfi >= 32 || trx >= 8 || ts >= 8)
if (tfi >= 32 || trx >= 8)
return NULL;
if (dir == GPRS_RLCMAC_UL_TBF)
tbf = bts->trx[trx].pdch[ts].ul_tbf[tfi];
tbf = bts->trx[trx].ul_tbf[tfi];
else
tbf = bts->trx[trx].pdch[ts].dl_tbf[tfi];
tbf = bts->trx[trx].dl_tbf[tfi];
if (!tbf)
return NULL;
@ -312,38 +312,24 @@ int alloc_algorithm_a(struct gprs_rlcmac_tbf *old_tbf,
}
tbf->tsc = pdch->tsc;
if (tbf->direction == GPRS_RLCMAC_UL_TBF) {
/* if TFI is free on TS */
if (!pdch->ul_tbf[tbf->tfi]) {
/* if USF available */
usf = find_free_usf(pdch, ts);
if (usf >= 0) {
LOGP(DRLCMAC, LOGL_DEBUG, "- Assign uplink "
"TS=%d USF=%d\n", ts, usf);
pdch->ul_tbf[tbf->tfi] = tbf;
tbf->pdch[ts] = pdch;
} else {
LOGP(DRLCMAC, LOGL_NOTICE, "- Failed "
"allocating TS=%d, no USF available\n",
ts);
return -EBUSY;
}
/* if USF available */
usf = find_free_usf(pdch, ts);
if (usf >= 0) {
LOGP(DRLCMAC, LOGL_DEBUG, "- Assign uplink "
"TS=%d USF=%d\n", ts, usf);
bts->trx[tbf->trx].ul_tbf[tbf->tfi] = tbf;
pdch->ul_tbf[tbf->tfi] = tbf;
tbf->pdch[ts] = pdch;
} else {
LOGP(DRLCMAC, LOGL_NOTICE, "- Failed allocating "
"TS=%d, TFI is not available\n", ts);
LOGP(DRLCMAC, LOGL_NOTICE, "- Failed "
"allocating TS=%d, no USF available\n", ts);
return -EBUSY;
}
} else {
/* if TFI is free on TS */
if (!pdch->dl_tbf[tbf->tfi]) {
LOGP(DRLCMAC, LOGL_DEBUG, "- Assign downlink TS=%d\n",
ts);
pdch->dl_tbf[tbf->tfi] = tbf;
tbf->pdch[ts] = pdch;
} else {
LOGP(DRLCMAC, LOGL_NOTICE, "- Failed allocating "
"TS=%d, TFI is not available\n", ts);
return -EBUSY;
}
LOGP(DRLCMAC, LOGL_DEBUG, "- Assign downlink TS=%d\n", ts);
bts->trx[tbf->trx].dl_tbf[tbf->tfi] = tbf;
pdch->dl_tbf[tbf->tfi] = tbf;
tbf->pdch[ts] = pdch;
}
/* the only one TS is the common TS */
tbf->first_common_ts = ts;
@ -474,18 +460,6 @@ int alloc_algorithm_b(struct gprs_rlcmac_tbf *old_tbf,
i++;
continue;
}
/* check if TFI for slot is available
* This is only possible for downlink TFI. */
if (tbf->direction == GPRS_RLCMAC_DL_TBF
&& pdch->dl_tbf[tbf->tfi]) {
LOGP(DRLCMAC, LOGL_DEBUG, "- Skipping TS %d, because "
"already assigned to other DL TBF with "
"TFI=%d\n", ts, tbf->tfi);
/* increase window for Type 1 */
if (Type == 1)
i++;
continue;
}
rx_window |= (1 << ts);
LOGP(DRLCMAC, LOGL_DEBUG, "- Selected DL TS %d\n", ts);
@ -634,16 +608,6 @@ int alloc_algorithm_b(struct gprs_rlcmac_tbf *old_tbf,
i++;
continue;
}
/* check if TFI for slot is available */
if (pdch->ul_tbf[tbf->tfi]) {
LOGP(DRLCMAC, LOGL_DEBUG, "- Skipping TS %d, "
"because already assigned to other "
"UL TBF with TFI=%d\n", ts, tbf->tfi);
/* increase window for Type 1 */
if (Type == 1)
i++;
continue;
}
/* check for free usf */
usf[ts] = find_free_usf(pdch, ts);
if (usf[ts] < 0) {
@ -703,6 +667,7 @@ int alloc_algorithm_b(struct gprs_rlcmac_tbf *old_tbf,
LOGP(DRLCMAC, LOGL_DEBUG, "- Assigning DL TS "
"%d\n", ts);
pdch = &bts->trx[tbf->trx].pdch[ts];
bts->trx[tbf->trx].dl_tbf[tbf->tfi] = tbf;
pdch->dl_tbf[tbf->tfi] = tbf;
tbf->pdch[ts] = pdch;
slotcount++;
@ -723,6 +688,7 @@ int alloc_algorithm_b(struct gprs_rlcmac_tbf *old_tbf,
LOGP(DRLCMAC, LOGL_DEBUG, "- Assigning UL TS "
"%d\n", ts);
pdch = &bts->trx[tbf->trx].pdch[ts];
bts->trx[tbf->trx].ul_tbf[tbf->tfi] = tbf;
pdch->ul_tbf[tbf->tfi] = tbf;
tbf->pdch[ts] = pdch;
tbf->dir.ul.usf[ts] = usf[ts];
@ -739,10 +705,12 @@ int alloc_algorithm_b(struct gprs_rlcmac_tbf *old_tbf,
static void tbf_unlink_pdch(struct gprs_rlcmac_tbf *tbf)
{
struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts;
struct gprs_rlcmac_pdch *pdch;
int ts;
if (tbf->direction == GPRS_RLCMAC_UL_TBF) {
bts->trx[tbf->trx].ul_tbf[tbf->tfi] = NULL;
for (ts = 0; ts < 8; ts++) {
pdch = tbf->pdch[ts];
if (pdch)
@ -750,6 +718,7 @@ static void tbf_unlink_pdch(struct gprs_rlcmac_tbf *tbf)
tbf->pdch[ts] = NULL;
}
} else {
bts->trx[tbf->trx].dl_tbf[tbf->tfi] = NULL;
for (ts = 0; ts < 8; ts++) {
pdch = tbf->pdch[ts];
if (pdch)

View File

@ -57,6 +57,8 @@ struct gprs_rlcmac_pdch {
struct gprs_rlcmac_trx {
uint16_t arfcn;
struct gprs_rlcmac_pdch pdch[8];
struct gprs_rlcmac_tbf *ul_tbf[32]; /* array of UL TBF, by UL TFI */
struct gprs_rlcmac_tbf *dl_tbf[32]; /* array of DL TBF, by DL TFI */
};
struct gprs_rlcmac_bts {
@ -253,7 +255,7 @@ struct gprs_rlcmac_tbf *tbf_alloc(struct gprs_rlcmac_tbf *old_tbf,
enum gprs_rlcmac_tbf_direction dir, uint8_t tfi, uint8_t trx,
uint8_t first_ts, uint8_t ms_class, uint8_t single_slot);
struct gprs_rlcmac_tbf *tbf_by_tfi(uint8_t tfi, uint8_t trx, uint8_t ts,
struct gprs_rlcmac_tbf *tbf_by_tfi(uint8_t tfi, uint8_t trx,
enum gprs_rlcmac_tbf_direction dir);
struct gprs_rlcmac_tbf *tbf_by_tlli(uint32_t tlli,

View File

@ -404,14 +404,14 @@ int gprs_rlcmac_rcv_control_block(bitvec *rlc_block, uint8_t trx, uint8_t ts,
} else {
if (ul_control_block->u.Packet_Resource_Request.ID.u.Global_TFI.UnionType) {
tfi = ul_control_block->u.Packet_Resource_Request.ID.u.Global_TFI.u.DOWNLINK_TFI;
tbf = tbf_by_tfi(tfi, trx, ts, GPRS_RLCMAC_DL_TBF);
tbf = tbf_by_tfi(tfi, trx, GPRS_RLCMAC_DL_TBF);
if (!tbf) {
LOGP(DRLCMAC, LOGL_NOTICE, "PACKET RESSOURCE REQ unknown downlink TBF=%d\n", tlli);
break;
}
} else {
tfi = ul_control_block->u.Packet_Resource_Request.ID.u.Global_TFI.u.UPLINK_TFI;
tbf = tbf_by_tfi(tfi, trx, ts, GPRS_RLCMAC_UL_TBF);
tbf = tbf_by_tfi(tfi, trx, GPRS_RLCMAC_UL_TBF);
if (!tbf) {
LOGP(DRLCMAC, LOGL_NOTICE, "PACKET RESSOURCE REQ unknown uplink TBF=%d\n", tlli);
break;
@ -782,7 +782,7 @@ int gprs_rlcmac_rcv_data_block_acknowledged(uint8_t trx, uint8_t ts,
}
/* find TBF inst from given TFI */
tbf = tbf_by_tfi(rh->tfi, trx, ts, GPRS_RLCMAC_UL_TBF);
tbf = tbf_by_tfi(rh->tfi, trx, GPRS_RLCMAC_UL_TBF);
if (!tbf) {
LOGP(DRLCMACUL, LOGL_NOTICE, "UL DATA unknown TBF=%d\n",
rh->tfi);

View File

@ -94,16 +94,15 @@ static void pcu_sock_close(struct pcu_sock_state *state)
/* disable all slots, kick all TBFs */
for (trx = 0; trx < 8; trx++) {
for (ts = 0; ts < 8; ts++) {
for (ts = 0; ts < 8; ts++)
bts->trx[trx].pdch[ts].enable = 0;
for (tfi = 0; tfi < 32; tfi++) {
tbf = bts->trx[trx].pdch[ts].ul_tbf[tfi];
if (tbf)
tbf_free(tbf);
tbf = bts->trx[trx].pdch[ts].dl_tbf[tfi];
if (tbf)
tbf_free(tbf);
}
for (tfi = 0; tfi < 32; tfi++) {
tbf = bts->trx[trx].ul_tbf[tfi];
if (tbf)
tbf_free(tbf);
tbf = bts->trx[trx].dl_tbf[tfi];
if (tbf)
tbf_free(tbf);
}
}