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:
parent
07e97cf8a5
commit
adb2f18538
|
@ -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: "
|
LOGP(DRLCMAC, LOGL_DEBUG, "Searching for first unallocated TFI: "
|
||||||
"TRX=%d first TS=%d\n", trx, ts);
|
"TRX=%d first TS=%d\n", trx, ts);
|
||||||
if (dir == GPRS_RLCMAC_UL_TBF)
|
if (dir == GPRS_RLCMAC_UL_TBF)
|
||||||
tbfp = pdch->ul_tbf;
|
tbfp = bts->trx[trx].ul_tbf;
|
||||||
else
|
else
|
||||||
tbfp = pdch->dl_tbf;
|
tbfp = bts->trx[trx].dl_tbf;
|
||||||
for (tfi = 0; tfi < 32; tfi++) {
|
for (tfi = 0; tfi < 32; tfi++) {
|
||||||
if (!tbfp[tfi])
|
if (!tbfp[tfi])
|
||||||
break;
|
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) */
|
/* 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)
|
enum gprs_rlcmac_tbf_direction dir)
|
||||||
{
|
{
|
||||||
struct gprs_rlcmac_tbf *tbf;
|
struct gprs_rlcmac_tbf *tbf;
|
||||||
struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts;
|
struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts;
|
||||||
|
|
||||||
if (tfi >= 32 || trx >= 8 || ts >= 8)
|
if (tfi >= 32 || trx >= 8)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (dir == GPRS_RLCMAC_UL_TBF)
|
if (dir == GPRS_RLCMAC_UL_TBF)
|
||||||
tbf = bts->trx[trx].pdch[ts].ul_tbf[tfi];
|
tbf = bts->trx[trx].ul_tbf[tfi];
|
||||||
else
|
else
|
||||||
tbf = bts->trx[trx].pdch[ts].dl_tbf[tfi];
|
tbf = bts->trx[trx].dl_tbf[tfi];
|
||||||
if (!tbf)
|
if (!tbf)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -312,38 +312,24 @@ int alloc_algorithm_a(struct gprs_rlcmac_tbf *old_tbf,
|
||||||
}
|
}
|
||||||
tbf->tsc = pdch->tsc;
|
tbf->tsc = pdch->tsc;
|
||||||
if (tbf->direction == GPRS_RLCMAC_UL_TBF) {
|
if (tbf->direction == GPRS_RLCMAC_UL_TBF) {
|
||||||
/* if TFI is free on TS */
|
/* if USF available */
|
||||||
if (!pdch->ul_tbf[tbf->tfi]) {
|
usf = find_free_usf(pdch, ts);
|
||||||
/* if USF available */
|
if (usf >= 0) {
|
||||||
usf = find_free_usf(pdch, ts);
|
LOGP(DRLCMAC, LOGL_DEBUG, "- Assign uplink "
|
||||||
if (usf >= 0) {
|
"TS=%d USF=%d\n", ts, usf);
|
||||||
LOGP(DRLCMAC, LOGL_DEBUG, "- Assign uplink "
|
bts->trx[tbf->trx].ul_tbf[tbf->tfi] = tbf;
|
||||||
"TS=%d USF=%d\n", ts, usf);
|
pdch->ul_tbf[tbf->tfi] = tbf;
|
||||||
pdch->ul_tbf[tbf->tfi] = tbf;
|
tbf->pdch[ts] = pdch;
|
||||||
tbf->pdch[ts] = pdch;
|
|
||||||
} else {
|
|
||||||
LOGP(DRLCMAC, LOGL_NOTICE, "- Failed "
|
|
||||||
"allocating TS=%d, no USF available\n",
|
|
||||||
ts);
|
|
||||||
return -EBUSY;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
LOGP(DRLCMAC, LOGL_NOTICE, "- Failed allocating "
|
LOGP(DRLCMAC, LOGL_NOTICE, "- Failed "
|
||||||
"TS=%d, TFI is not available\n", ts);
|
"allocating TS=%d, no USF available\n", ts);
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* if TFI is free on TS */
|
LOGP(DRLCMAC, LOGL_DEBUG, "- Assign downlink TS=%d\n", ts);
|
||||||
if (!pdch->dl_tbf[tbf->tfi]) {
|
bts->trx[tbf->trx].dl_tbf[tbf->tfi] = tbf;
|
||||||
LOGP(DRLCMAC, LOGL_DEBUG, "- Assign downlink TS=%d\n",
|
pdch->dl_tbf[tbf->tfi] = tbf;
|
||||||
ts);
|
tbf->pdch[ts] = pdch;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/* the only one TS is the common TS */
|
/* the only one TS is the common TS */
|
||||||
tbf->first_common_ts = ts;
|
tbf->first_common_ts = ts;
|
||||||
|
@ -474,18 +460,6 @@ int alloc_algorithm_b(struct gprs_rlcmac_tbf *old_tbf,
|
||||||
i++;
|
i++;
|
||||||
continue;
|
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);
|
rx_window |= (1 << ts);
|
||||||
LOGP(DRLCMAC, LOGL_DEBUG, "- Selected DL TS %d\n", 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++;
|
i++;
|
||||||
continue;
|
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 */
|
/* check for free usf */
|
||||||
usf[ts] = find_free_usf(pdch, ts);
|
usf[ts] = find_free_usf(pdch, ts);
|
||||||
if (usf[ts] < 0) {
|
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 "
|
LOGP(DRLCMAC, LOGL_DEBUG, "- Assigning DL TS "
|
||||||
"%d\n", ts);
|
"%d\n", ts);
|
||||||
pdch = &bts->trx[tbf->trx].pdch[ts];
|
pdch = &bts->trx[tbf->trx].pdch[ts];
|
||||||
|
bts->trx[tbf->trx].dl_tbf[tbf->tfi] = tbf;
|
||||||
pdch->dl_tbf[tbf->tfi] = tbf;
|
pdch->dl_tbf[tbf->tfi] = tbf;
|
||||||
tbf->pdch[ts] = pdch;
|
tbf->pdch[ts] = pdch;
|
||||||
slotcount++;
|
slotcount++;
|
||||||
|
@ -723,6 +688,7 @@ int alloc_algorithm_b(struct gprs_rlcmac_tbf *old_tbf,
|
||||||
LOGP(DRLCMAC, LOGL_DEBUG, "- Assigning UL TS "
|
LOGP(DRLCMAC, LOGL_DEBUG, "- Assigning UL TS "
|
||||||
"%d\n", ts);
|
"%d\n", ts);
|
||||||
pdch = &bts->trx[tbf->trx].pdch[ts];
|
pdch = &bts->trx[tbf->trx].pdch[ts];
|
||||||
|
bts->trx[tbf->trx].ul_tbf[tbf->tfi] = tbf;
|
||||||
pdch->ul_tbf[tbf->tfi] = tbf;
|
pdch->ul_tbf[tbf->tfi] = tbf;
|
||||||
tbf->pdch[ts] = pdch;
|
tbf->pdch[ts] = pdch;
|
||||||
tbf->dir.ul.usf[ts] = usf[ts];
|
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)
|
static void tbf_unlink_pdch(struct gprs_rlcmac_tbf *tbf)
|
||||||
{
|
{
|
||||||
|
struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts;
|
||||||
struct gprs_rlcmac_pdch *pdch;
|
struct gprs_rlcmac_pdch *pdch;
|
||||||
int ts;
|
int ts;
|
||||||
|
|
||||||
if (tbf->direction == GPRS_RLCMAC_UL_TBF) {
|
if (tbf->direction == GPRS_RLCMAC_UL_TBF) {
|
||||||
|
bts->trx[tbf->trx].ul_tbf[tbf->tfi] = NULL;
|
||||||
for (ts = 0; ts < 8; ts++) {
|
for (ts = 0; ts < 8; ts++) {
|
||||||
pdch = tbf->pdch[ts];
|
pdch = tbf->pdch[ts];
|
||||||
if (pdch)
|
if (pdch)
|
||||||
|
@ -750,6 +718,7 @@ static void tbf_unlink_pdch(struct gprs_rlcmac_tbf *tbf)
|
||||||
tbf->pdch[ts] = NULL;
|
tbf->pdch[ts] = NULL;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
bts->trx[tbf->trx].dl_tbf[tbf->tfi] = NULL;
|
||||||
for (ts = 0; ts < 8; ts++) {
|
for (ts = 0; ts < 8; ts++) {
|
||||||
pdch = tbf->pdch[ts];
|
pdch = tbf->pdch[ts];
|
||||||
if (pdch)
|
if (pdch)
|
||||||
|
|
|
@ -57,6 +57,8 @@ struct gprs_rlcmac_pdch {
|
||||||
struct gprs_rlcmac_trx {
|
struct gprs_rlcmac_trx {
|
||||||
uint16_t arfcn;
|
uint16_t arfcn;
|
||||||
struct gprs_rlcmac_pdch pdch[8];
|
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 {
|
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,
|
enum gprs_rlcmac_tbf_direction dir, uint8_t tfi, uint8_t trx,
|
||||||
uint8_t first_ts, uint8_t ms_class, uint8_t single_slot);
|
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);
|
enum gprs_rlcmac_tbf_direction dir);
|
||||||
|
|
||||||
struct gprs_rlcmac_tbf *tbf_by_tlli(uint32_t tlli,
|
struct gprs_rlcmac_tbf *tbf_by_tlli(uint32_t tlli,
|
||||||
|
|
|
@ -404,14 +404,14 @@ int gprs_rlcmac_rcv_control_block(bitvec *rlc_block, uint8_t trx, uint8_t ts,
|
||||||
} else {
|
} else {
|
||||||
if (ul_control_block->u.Packet_Resource_Request.ID.u.Global_TFI.UnionType) {
|
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;
|
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) {
|
if (!tbf) {
|
||||||
LOGP(DRLCMAC, LOGL_NOTICE, "PACKET RESSOURCE REQ unknown downlink TBF=%d\n", tlli);
|
LOGP(DRLCMAC, LOGL_NOTICE, "PACKET RESSOURCE REQ unknown downlink TBF=%d\n", tlli);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tfi = ul_control_block->u.Packet_Resource_Request.ID.u.Global_TFI.u.UPLINK_TFI;
|
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) {
|
if (!tbf) {
|
||||||
LOGP(DRLCMAC, LOGL_NOTICE, "PACKET RESSOURCE REQ unknown uplink TBF=%d\n", tlli);
|
LOGP(DRLCMAC, LOGL_NOTICE, "PACKET RESSOURCE REQ unknown uplink TBF=%d\n", tlli);
|
||||||
break;
|
break;
|
||||||
|
@ -782,7 +782,7 @@ int gprs_rlcmac_rcv_data_block_acknowledged(uint8_t trx, uint8_t ts,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* find TBF inst from given TFI */
|
/* 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) {
|
if (!tbf) {
|
||||||
LOGP(DRLCMACUL, LOGL_NOTICE, "UL DATA unknown TBF=%d\n",
|
LOGP(DRLCMACUL, LOGL_NOTICE, "UL DATA unknown TBF=%d\n",
|
||||||
rh->tfi);
|
rh->tfi);
|
||||||
|
|
|
@ -94,16 +94,15 @@ static void pcu_sock_close(struct pcu_sock_state *state)
|
||||||
|
|
||||||
/* disable all slots, kick all TBFs */
|
/* disable all slots, kick all TBFs */
|
||||||
for (trx = 0; trx < 8; trx++) {
|
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;
|
bts->trx[trx].pdch[ts].enable = 0;
|
||||||
for (tfi = 0; tfi < 32; tfi++) {
|
for (tfi = 0; tfi < 32; tfi++) {
|
||||||
tbf = bts->trx[trx].pdch[ts].ul_tbf[tfi];
|
tbf = bts->trx[trx].ul_tbf[tfi];
|
||||||
if (tbf)
|
if (tbf)
|
||||||
tbf_free(tbf);
|
tbf_free(tbf);
|
||||||
tbf = bts->trx[trx].pdch[ts].dl_tbf[tfi];
|
tbf = bts->trx[trx].dl_tbf[tfi];
|
||||||
if (tbf)
|
if (tbf)
|
||||||
tbf_free(tbf);
|
tbf_free(tbf);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue