Add new PDCH UL Controller, drop SBAllocator class
Right now we handle different types of UL allocations in different
classes like PollAllocator and SBAllocator, and they usually don't take
into account the other one in most cases. Furthermore, those objects are
usually per-BTS object, instead of per PDCH object.
This is a first step towards having a unified per-PDCH controller which
takes care of controlling what is scheduled and hence expected on the
uplink. Each PDCH has a UL Controller which keeps track of all reserved
uplink frame, be it SB, RRBP poll or USF assigned, all under the same
API.
As a first step, only the SBA part is fully implemented and used (being
it the easiest part to replace); TBF poll+usf will come in follow-up
patches later on. As a result, the SBAllocator per-BTS class dissappears
but some of its code is refactored/reused to provide more features to the
gprs_rlcmac_sba object, which is also further integrated into the new UL
Controller.
Related: OS#5020
Change-Id: I84b24beea4a1aa2c1528f41435f77bd16df2b947
2021-03-08 13:57:58 +00:00
|
|
|
/* pdch_ul_controller.c
|
|
|
|
*
|
|
|
|
* Copyright (C) 2021 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
|
|
|
|
* Author: Pau Espin Pedrol <pespin@sysmocom.de>
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <talloc.h>
|
|
|
|
|
|
|
|
#include "pdch_ul_controller.h"
|
|
|
|
#include "bts.h"
|
|
|
|
#include "sba.h"
|
|
|
|
#include "pdch.h"
|
2021-03-09 16:18:12 +00:00
|
|
|
#include "pcu_utils.h"
|
2021-03-24 13:45:43 +00:00
|
|
|
#include "tbf_ul.h"
|
Add new PDCH UL Controller, drop SBAllocator class
Right now we handle different types of UL allocations in different
classes like PollAllocator and SBAllocator, and they usually don't take
into account the other one in most cases. Furthermore, those objects are
usually per-BTS object, instead of per PDCH object.
This is a first step towards having a unified per-PDCH controller which
takes care of controlling what is scheduled and hence expected on the
uplink. Each PDCH has a UL Controller which keeps track of all reserved
uplink frame, be it SB, RRBP poll or USF assigned, all under the same
API.
As a first step, only the SBA part is fully implemented and used (being
it the easiest part to replace); TBF poll+usf will come in follow-up
patches later on. As a result, the SBAllocator per-BTS class dissappears
but some of its code is refactored/reused to provide more features to the
gprs_rlcmac_sba object, which is also further integrated into the new UL
Controller.
Related: OS#5020
Change-Id: I84b24beea4a1aa2c1528f41435f77bd16df2b947
2021-03-08 13:57:58 +00:00
|
|
|
|
|
|
|
/* TS 44.060 Table 10.4.5.1 states maximum RRBP is N + 26. Give extra space for time diff between Tx and Rx? */
|
|
|
|
#define MAX_FN_RESERVED (27 + 50)
|
|
|
|
|
|
|
|
const struct value_string pdch_ul_node_names[] = {
|
|
|
|
{ PDCH_ULC_NODE_TBF_USF, "USF" },
|
|
|
|
{ PDCH_ULC_NODE_TBF_POLL, "POLL" },
|
|
|
|
{ PDCH_ULC_NODE_SBA, "SBA" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
2021-06-07 16:13:23 +00:00
|
|
|
const struct value_string pdch_ulc_tbf_poll_reason_names[] = {
|
|
|
|
{ PDCH_ULC_POLL_UL_ASS, "UL_ASS" },
|
|
|
|
{ PDCH_ULC_POLL_DL_ASS, "DL_ASS" },
|
|
|
|
{ PDCH_ULC_POLL_UL_ACK, "UL_ACK" },
|
|
|
|
{ PDCH_ULC_POLL_DL_ACK, "DL_ACK" },
|
|
|
|
{ PDCH_ULC_POLL_CELL_CHG_CONTINUE, "CELL_CHG_CONTINUE" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
2021-03-12 17:24:57 +00:00
|
|
|
#define GSM_MAX_FN_THRESH (GSM_MAX_FN >> 1)
|
|
|
|
/* 0: equal, -1: fn1 BEFORE fn2, 1: fn1 AFTER fn2 */
|
|
|
|
static inline int fn_cmp(uint32_t fn1, uint32_t fn2)
|
|
|
|
{
|
|
|
|
if (fn1 == fn2)
|
|
|
|
return 0;
|
|
|
|
/* FN1 goes before FN2: */
|
|
|
|
if ((fn1 < fn2 && (fn2 - fn1) < GSM_MAX_FN_THRESH) ||
|
|
|
|
(fn1 > fn2 && (fn1 - fn2) > GSM_MAX_FN_THRESH))
|
|
|
|
return -1;
|
|
|
|
/* FN1 goes after FN2: */
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
Add new PDCH UL Controller, drop SBAllocator class
Right now we handle different types of UL allocations in different
classes like PollAllocator and SBAllocator, and they usually don't take
into account the other one in most cases. Furthermore, those objects are
usually per-BTS object, instead of per PDCH object.
This is a first step towards having a unified per-PDCH controller which
takes care of controlling what is scheduled and hence expected on the
uplink. Each PDCH has a UL Controller which keeps track of all reserved
uplink frame, be it SB, RRBP poll or USF assigned, all under the same
API.
As a first step, only the SBA part is fully implemented and used (being
it the easiest part to replace); TBF poll+usf will come in follow-up
patches later on. As a result, the SBAllocator per-BTS class dissappears
but some of its code is refactored/reused to provide more features to the
gprs_rlcmac_sba object, which is also further integrated into the new UL
Controller.
Related: OS#5020
Change-Id: I84b24beea4a1aa2c1528f41435f77bd16df2b947
2021-03-08 13:57:58 +00:00
|
|
|
struct pdch_ulc *pdch_ulc_alloc(struct gprs_rlcmac_pdch *pdch, void *ctx)
|
|
|
|
{
|
|
|
|
struct pdch_ulc* ulc;
|
|
|
|
ulc = talloc_zero(ctx, struct pdch_ulc);
|
|
|
|
if (!ulc)
|
|
|
|
return ulc;
|
|
|
|
|
|
|
|
ulc->pdch = pdch;
|
|
|
|
ulc->pool_ctx = talloc_pool(ulc, sizeof(struct pdch_ulc_node) * MAX_FN_RESERVED);
|
|
|
|
return ulc;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct pdch_ulc_node *pdch_ulc_get_node(struct pdch_ulc *ulc, uint32_t fn)
|
|
|
|
{
|
2021-03-29 09:29:22 +00:00
|
|
|
struct rb_node *node = ulc->tree_root.rb_node;
|
Add new PDCH UL Controller, drop SBAllocator class
Right now we handle different types of UL allocations in different
classes like PollAllocator and SBAllocator, and they usually don't take
into account the other one in most cases. Furthermore, those objects are
usually per-BTS object, instead of per PDCH object.
This is a first step towards having a unified per-PDCH controller which
takes care of controlling what is scheduled and hence expected on the
uplink. Each PDCH has a UL Controller which keeps track of all reserved
uplink frame, be it SB, RRBP poll or USF assigned, all under the same
API.
As a first step, only the SBA part is fully implemented and used (being
it the easiest part to replace); TBF poll+usf will come in follow-up
patches later on. As a result, the SBAllocator per-BTS class dissappears
but some of its code is refactored/reused to provide more features to the
gprs_rlcmac_sba object, which is also further integrated into the new UL
Controller.
Related: OS#5020
Change-Id: I84b24beea4a1aa2c1528f41435f77bd16df2b947
2021-03-08 13:57:58 +00:00
|
|
|
struct pdch_ulc_node *it;
|
2021-03-12 17:24:57 +00:00
|
|
|
int res;
|
2021-03-29 09:29:22 +00:00
|
|
|
|
|
|
|
while (node) {
|
|
|
|
it = rb_entry(node, struct pdch_ulc_node, node);
|
2021-03-12 17:24:57 +00:00
|
|
|
res = fn_cmp(it->fn, fn);
|
|
|
|
if (res > 0) /* it->fn AFTER fn */
|
2021-03-29 09:29:22 +00:00
|
|
|
node = node->rb_left;
|
|
|
|
else if (res < 0) /* it->fn BEFORE fn */
|
|
|
|
node = node->rb_right;
|
|
|
|
else /* it->fn == fn */
|
|
|
|
return it;
|
Add new PDCH UL Controller, drop SBAllocator class
Right now we handle different types of UL allocations in different
classes like PollAllocator and SBAllocator, and they usually don't take
into account the other one in most cases. Furthermore, those objects are
usually per-BTS object, instead of per PDCH object.
This is a first step towards having a unified per-PDCH controller which
takes care of controlling what is scheduled and hence expected on the
uplink. Each PDCH has a UL Controller which keeps track of all reserved
uplink frame, be it SB, RRBP poll or USF assigned, all under the same
API.
As a first step, only the SBA part is fully implemented and used (being
it the easiest part to replace); TBF poll+usf will come in follow-up
patches later on. As a result, the SBAllocator per-BTS class dissappears
but some of its code is refactored/reused to provide more features to the
gprs_rlcmac_sba object, which is also further integrated into the new UL
Controller.
Related: OS#5020
Change-Id: I84b24beea4a1aa2c1528f41435f77bd16df2b947
2021-03-08 13:57:58 +00:00
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
struct pdch_ulc_node *pdch_ulc_pop_node(struct pdch_ulc *ulc, uint32_t fn)
|
|
|
|
{
|
|
|
|
struct pdch_ulc_node *item = pdch_ulc_get_node(ulc, fn);
|
|
|
|
if (!item)
|
|
|
|
return NULL;
|
|
|
|
rb_erase(&item->node, &ulc->tree_root);
|
|
|
|
return item;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct gprs_rlcmac_sba *pdch_ulc_get_sba(struct pdch_ulc *ulc, uint32_t fn)
|
|
|
|
{
|
|
|
|
struct pdch_ulc_node *item = pdch_ulc_get_node(ulc, fn);
|
|
|
|
if (!item || item->type != PDCH_ULC_NODE_SBA)
|
|
|
|
return NULL;
|
|
|
|
return item->sba.sba;
|
|
|
|
}
|
|
|
|
|
2021-03-11 15:59:50 +00:00
|
|
|
struct gprs_rlcmac_tbf *pdch_ulc_get_tbf_poll(struct pdch_ulc *ulc, uint32_t fn)
|
|
|
|
{
|
|
|
|
struct pdch_ulc_node *item = pdch_ulc_get_node(ulc, fn);
|
|
|
|
if (!item || item->type != PDCH_ULC_NODE_TBF_POLL)
|
|
|
|
return NULL;
|
|
|
|
return item->tbf_poll.poll_tbf;
|
|
|
|
}
|
|
|
|
|
Add new PDCH UL Controller, drop SBAllocator class
Right now we handle different types of UL allocations in different
classes like PollAllocator and SBAllocator, and they usually don't take
into account the other one in most cases. Furthermore, those objects are
usually per-BTS object, instead of per PDCH object.
This is a first step towards having a unified per-PDCH controller which
takes care of controlling what is scheduled and hence expected on the
uplink. Each PDCH has a UL Controller which keeps track of all reserved
uplink frame, be it SB, RRBP poll or USF assigned, all under the same
API.
As a first step, only the SBA part is fully implemented and used (being
it the easiest part to replace); TBF poll+usf will come in follow-up
patches later on. As a result, the SBAllocator per-BTS class dissappears
but some of its code is refactored/reused to provide more features to the
gprs_rlcmac_sba object, which is also further integrated into the new UL
Controller.
Related: OS#5020
Change-Id: I84b24beea4a1aa2c1528f41435f77bd16df2b947
2021-03-08 13:57:58 +00:00
|
|
|
bool pdch_ulc_fn_is_free(struct pdch_ulc *ulc, uint32_t fn)
|
|
|
|
{
|
|
|
|
return !pdch_ulc_get_node(ulc, fn);
|
|
|
|
}
|
|
|
|
|
2021-03-29 11:49:43 +00:00
|
|
|
struct rrbp_opt {
|
|
|
|
uint8_t offset;
|
|
|
|
enum rrbp_field coding;
|
|
|
|
};
|
|
|
|
|
2021-03-09 16:18:12 +00:00
|
|
|
int pdch_ulc_get_next_free_rrbp_fn(struct pdch_ulc *ulc, uint32_t fn, uint32_t *poll_fn, unsigned int *rrbp)
|
|
|
|
{
|
2021-03-29 11:49:43 +00:00
|
|
|
uint8_t i;
|
|
|
|
static const struct rrbp_opt rrbp_list[] = {
|
|
|
|
{ 13, RRBP_N_plus_13 },
|
|
|
|
{ 17, RRBP_N_plus_17_18 },
|
|
|
|
{ 18, RRBP_N_plus_17_18 },
|
|
|
|
{ 21, RRBP_N_plus_21_22 },
|
|
|
|
{ 22, RRBP_N_plus_21_22 },
|
|
|
|
{ 26, RRBP_N_plus_26 },
|
|
|
|
};
|
|
|
|
|
|
|
|
for (i = 0; i < ARRAY_SIZE(rrbp_list); i++) {
|
|
|
|
uint32_t new_poll_fn = next_fn(fn, rrbp_list[i].offset);
|
|
|
|
if (!fn_valid(new_poll_fn))
|
|
|
|
continue;
|
|
|
|
if (pdch_ulc_fn_is_free(ulc, new_poll_fn)) {
|
|
|
|
LOGPDCH(ulc->pdch, DRLCMAC, LOGL_DEBUG, "POLL scheduled at FN %" PRIu32
|
|
|
|
" + %" PRIu8 " = %" PRIu32 "\n",
|
|
|
|
fn, rrbp_list[i].offset, new_poll_fn);
|
|
|
|
*poll_fn = new_poll_fn;
|
|
|
|
*rrbp = (unsigned int)rrbp_list[i].coding;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
LOGPDCH(ulc->pdch, DRLCMAC, LOGL_DEBUG, "UL block already scheduled at FN %" PRIu32
|
|
|
|
" + %" PRIu8 " = %" PRIu32 "\n",
|
|
|
|
fn, rrbp_list[i].offset, new_poll_fn);
|
2021-03-09 16:18:12 +00:00
|
|
|
|
2021-03-29 11:49:43 +00:00
|
|
|
}
|
|
|
|
LOGPDCH(ulc->pdch, DRLCMAC, LOGL_ERROR, "FN=%" PRIu32 " "
|
|
|
|
"Failed allocating POLL, all RRBP values are already reserved!\n", fn);
|
|
|
|
return -EBUSY;
|
2021-03-09 16:18:12 +00:00
|
|
|
}
|
|
|
|
|
2021-03-29 10:13:13 +00:00
|
|
|
/* Get next free (unreserved) FN which is not located in time before "start_fn" */
|
|
|
|
uint32_t pdch_ulc_get_next_free_fn(struct pdch_ulc *ulc, uint32_t start_fn)
|
|
|
|
{
|
|
|
|
struct rb_node *node;
|
|
|
|
struct pdch_ulc_node *it;
|
|
|
|
int res;
|
|
|
|
uint32_t check_fn = start_fn;
|
|
|
|
|
|
|
|
for (node = rb_first(&ulc->tree_root); node; node = rb_next(node)) {
|
|
|
|
it = container_of(node, struct pdch_ulc_node, node);
|
|
|
|
res = fn_cmp(it->fn, check_fn);
|
|
|
|
if (res > 0) { /* it->fn AFTER check_fn */
|
|
|
|
/* Next reserved FN is passed check_fn, hence it means check_fn is free */
|
|
|
|
return check_fn;
|
|
|
|
}
|
|
|
|
/* if it->fn < check_fn, simply continue iterating, we want to reach at least check_fn */
|
|
|
|
if (res == 0)/* it->fn == fn */
|
|
|
|
check_fn = fn_next_block(check_fn);
|
|
|
|
/* if it->fn < check_fn, simply continue iterating, we want to reach at least check_fn */
|
|
|
|
}
|
|
|
|
return check_fn;
|
|
|
|
}
|
|
|
|
|
Add new PDCH UL Controller, drop SBAllocator class
Right now we handle different types of UL allocations in different
classes like PollAllocator and SBAllocator, and they usually don't take
into account the other one in most cases. Furthermore, those objects are
usually per-BTS object, instead of per PDCH object.
This is a first step towards having a unified per-PDCH controller which
takes care of controlling what is scheduled and hence expected on the
uplink. Each PDCH has a UL Controller which keeps track of all reserved
uplink frame, be it SB, RRBP poll or USF assigned, all under the same
API.
As a first step, only the SBA part is fully implemented and used (being
it the easiest part to replace); TBF poll+usf will come in follow-up
patches later on. As a result, the SBAllocator per-BTS class dissappears
but some of its code is refactored/reused to provide more features to the
gprs_rlcmac_sba object, which is also further integrated into the new UL
Controller.
Related: OS#5020
Change-Id: I84b24beea4a1aa2c1528f41435f77bd16df2b947
2021-03-08 13:57:58 +00:00
|
|
|
static struct pdch_ulc_node *_alloc_node(struct pdch_ulc *ulc, uint32_t fn)
|
|
|
|
{
|
|
|
|
struct pdch_ulc_node *node;
|
|
|
|
node = talloc_zero(ulc->pool_ctx, struct pdch_ulc_node);
|
|
|
|
node->fn = fn;
|
|
|
|
return node;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int pdch_ulc_add_node(struct pdch_ulc *ulc, struct pdch_ulc_node *item)
|
|
|
|
{
|
|
|
|
struct rb_node **n = &(ulc->tree_root.rb_node);
|
|
|
|
struct rb_node *parent = NULL;
|
|
|
|
|
|
|
|
while (*n) {
|
|
|
|
struct pdch_ulc_node *it;
|
2021-03-12 17:24:57 +00:00
|
|
|
int res;
|
Add new PDCH UL Controller, drop SBAllocator class
Right now we handle different types of UL allocations in different
classes like PollAllocator and SBAllocator, and they usually don't take
into account the other one in most cases. Furthermore, those objects are
usually per-BTS object, instead of per PDCH object.
This is a first step towards having a unified per-PDCH controller which
takes care of controlling what is scheduled and hence expected on the
uplink. Each PDCH has a UL Controller which keeps track of all reserved
uplink frame, be it SB, RRBP poll or USF assigned, all under the same
API.
As a first step, only the SBA part is fully implemented and used (being
it the easiest part to replace); TBF poll+usf will come in follow-up
patches later on. As a result, the SBAllocator per-BTS class dissappears
but some of its code is refactored/reused to provide more features to the
gprs_rlcmac_sba object, which is also further integrated into the new UL
Controller.
Related: OS#5020
Change-Id: I84b24beea4a1aa2c1528f41435f77bd16df2b947
2021-03-08 13:57:58 +00:00
|
|
|
|
|
|
|
it = container_of(*n, struct pdch_ulc_node, node);
|
|
|
|
|
|
|
|
parent = *n;
|
2021-03-12 17:24:57 +00:00
|
|
|
res = fn_cmp(item->fn, it->fn);
|
|
|
|
if (res < 0) { /* item->fn "BEFORE" it->fn */
|
Add new PDCH UL Controller, drop SBAllocator class
Right now we handle different types of UL allocations in different
classes like PollAllocator and SBAllocator, and they usually don't take
into account the other one in most cases. Furthermore, those objects are
usually per-BTS object, instead of per PDCH object.
This is a first step towards having a unified per-PDCH controller which
takes care of controlling what is scheduled and hence expected on the
uplink. Each PDCH has a UL Controller which keeps track of all reserved
uplink frame, be it SB, RRBP poll or USF assigned, all under the same
API.
As a first step, only the SBA part is fully implemented and used (being
it the easiest part to replace); TBF poll+usf will come in follow-up
patches later on. As a result, the SBAllocator per-BTS class dissappears
but some of its code is refactored/reused to provide more features to the
gprs_rlcmac_sba object, which is also further integrated into the new UL
Controller.
Related: OS#5020
Change-Id: I84b24beea4a1aa2c1528f41435f77bd16df2b947
2021-03-08 13:57:58 +00:00
|
|
|
n = &((*n)->rb_left);
|
2021-03-12 17:24:57 +00:00
|
|
|
} else if (res > 0) { /* item->fn "AFTER" it->fn */
|
Add new PDCH UL Controller, drop SBAllocator class
Right now we handle different types of UL allocations in different
classes like PollAllocator and SBAllocator, and they usually don't take
into account the other one in most cases. Furthermore, those objects are
usually per-BTS object, instead of per PDCH object.
This is a first step towards having a unified per-PDCH controller which
takes care of controlling what is scheduled and hence expected on the
uplink. Each PDCH has a UL Controller which keeps track of all reserved
uplink frame, be it SB, RRBP poll or USF assigned, all under the same
API.
As a first step, only the SBA part is fully implemented and used (being
it the easiest part to replace); TBF poll+usf will come in follow-up
patches later on. As a result, the SBAllocator per-BTS class dissappears
but some of its code is refactored/reused to provide more features to the
gprs_rlcmac_sba object, which is also further integrated into the new UL
Controller.
Related: OS#5020
Change-Id: I84b24beea4a1aa2c1528f41435f77bd16df2b947
2021-03-08 13:57:58 +00:00
|
|
|
n = &((*n)->rb_right);
|
|
|
|
} else {
|
|
|
|
LOGPDCH(ulc->pdch, DRLCMAC, LOGL_ERROR,
|
|
|
|
"Trying to reserve already reserved FN %u\n",
|
|
|
|
item->fn);
|
|
|
|
return -EEXIST;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
rb_link_node(&item->node, parent, n);
|
|
|
|
rb_insert_color(&item->node, &ulc->tree_root);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int pdch_ulc_reserve_tbf_usf(struct pdch_ulc *ulc, uint32_t fn, struct gprs_rlcmac_ul_tbf *ul_tbf)
|
|
|
|
{
|
2021-03-24 13:06:15 +00:00
|
|
|
struct pdch_ulc_node *item = _alloc_node(ulc, fn);
|
|
|
|
item->type = PDCH_ULC_NODE_TBF_USF;
|
|
|
|
item->tbf_usf.ul_tbf = ul_tbf;
|
|
|
|
return pdch_ulc_add_node(ulc, item);
|
Add new PDCH UL Controller, drop SBAllocator class
Right now we handle different types of UL allocations in different
classes like PollAllocator and SBAllocator, and they usually don't take
into account the other one in most cases. Furthermore, those objects are
usually per-BTS object, instead of per PDCH object.
This is a first step towards having a unified per-PDCH controller which
takes care of controlling what is scheduled and hence expected on the
uplink. Each PDCH has a UL Controller which keeps track of all reserved
uplink frame, be it SB, RRBP poll or USF assigned, all under the same
API.
As a first step, only the SBA part is fully implemented and used (being
it the easiest part to replace); TBF poll+usf will come in follow-up
patches later on. As a result, the SBAllocator per-BTS class dissappears
but some of its code is refactored/reused to provide more features to the
gprs_rlcmac_sba object, which is also further integrated into the new UL
Controller.
Related: OS#5020
Change-Id: I84b24beea4a1aa2c1528f41435f77bd16df2b947
2021-03-08 13:57:58 +00:00
|
|
|
}
|
|
|
|
|
2021-03-29 16:15:30 +00:00
|
|
|
int pdch_ulc_reserve_tbf_poll(struct pdch_ulc *ulc, uint32_t fn, struct gprs_rlcmac_tbf *tbf, enum pdch_ulc_tbf_poll_reason reason)
|
Add new PDCH UL Controller, drop SBAllocator class
Right now we handle different types of UL allocations in different
classes like PollAllocator and SBAllocator, and they usually don't take
into account the other one in most cases. Furthermore, those objects are
usually per-BTS object, instead of per PDCH object.
This is a first step towards having a unified per-PDCH controller which
takes care of controlling what is scheduled and hence expected on the
uplink. Each PDCH has a UL Controller which keeps track of all reserved
uplink frame, be it SB, RRBP poll or USF assigned, all under the same
API.
As a first step, only the SBA part is fully implemented and used (being
it the easiest part to replace); TBF poll+usf will come in follow-up
patches later on. As a result, the SBAllocator per-BTS class dissappears
but some of its code is refactored/reused to provide more features to the
gprs_rlcmac_sba object, which is also further integrated into the new UL
Controller.
Related: OS#5020
Change-Id: I84b24beea4a1aa2c1528f41435f77bd16df2b947
2021-03-08 13:57:58 +00:00
|
|
|
{
|
2021-03-09 16:18:12 +00:00
|
|
|
struct pdch_ulc_node *item = _alloc_node(ulc, fn);
|
|
|
|
item->type = PDCH_ULC_NODE_TBF_POLL;
|
|
|
|
item->tbf_poll.poll_tbf = tbf;
|
2021-03-29 16:15:30 +00:00
|
|
|
item->tbf_poll.reason = reason;
|
2021-03-09 16:18:12 +00:00
|
|
|
return pdch_ulc_add_node(ulc, item);
|
Add new PDCH UL Controller, drop SBAllocator class
Right now we handle different types of UL allocations in different
classes like PollAllocator and SBAllocator, and they usually don't take
into account the other one in most cases. Furthermore, those objects are
usually per-BTS object, instead of per PDCH object.
This is a first step towards having a unified per-PDCH controller which
takes care of controlling what is scheduled and hence expected on the
uplink. Each PDCH has a UL Controller which keeps track of all reserved
uplink frame, be it SB, RRBP poll or USF assigned, all under the same
API.
As a first step, only the SBA part is fully implemented and used (being
it the easiest part to replace); TBF poll+usf will come in follow-up
patches later on. As a result, the SBAllocator per-BTS class dissappears
but some of its code is refactored/reused to provide more features to the
gprs_rlcmac_sba object, which is also further integrated into the new UL
Controller.
Related: OS#5020
Change-Id: I84b24beea4a1aa2c1528f41435f77bd16df2b947
2021-03-08 13:57:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int pdch_ulc_reserve_sba(struct pdch_ulc *ulc, struct gprs_rlcmac_sba *sba)
|
|
|
|
{
|
|
|
|
struct pdch_ulc_node *item = _alloc_node(ulc, sba->fn);
|
|
|
|
item->type = PDCH_ULC_NODE_SBA;
|
|
|
|
item->sba.sba = sba;
|
|
|
|
return pdch_ulc_add_node(ulc, item);
|
|
|
|
}
|
|
|
|
|
2021-03-24 13:02:49 +00:00
|
|
|
void pdch_ulc_release_node(struct pdch_ulc *ulc, struct pdch_ulc_node *item)
|
|
|
|
{
|
|
|
|
rb_erase(&item->node, &ulc->tree_root);
|
|
|
|
talloc_free(item);
|
|
|
|
}
|
|
|
|
|
Add new PDCH UL Controller, drop SBAllocator class
Right now we handle different types of UL allocations in different
classes like PollAllocator and SBAllocator, and they usually don't take
into account the other one in most cases. Furthermore, those objects are
usually per-BTS object, instead of per PDCH object.
This is a first step towards having a unified per-PDCH controller which
takes care of controlling what is scheduled and hence expected on the
uplink. Each PDCH has a UL Controller which keeps track of all reserved
uplink frame, be it SB, RRBP poll or USF assigned, all under the same
API.
As a first step, only the SBA part is fully implemented and used (being
it the easiest part to replace); TBF poll+usf will come in follow-up
patches later on. As a result, the SBAllocator per-BTS class dissappears
but some of its code is refactored/reused to provide more features to the
gprs_rlcmac_sba object, which is also further integrated into the new UL
Controller.
Related: OS#5020
Change-Id: I84b24beea4a1aa2c1528f41435f77bd16df2b947
2021-03-08 13:57:58 +00:00
|
|
|
int pdch_ulc_release_fn(struct pdch_ulc *ulc, uint32_t fn)
|
|
|
|
{
|
|
|
|
struct pdch_ulc_node *item = pdch_ulc_get_node(ulc, fn);
|
|
|
|
if (!item)
|
|
|
|
return -ENOKEY;
|
2021-03-24 13:02:49 +00:00
|
|
|
pdch_ulc_release_node(ulc, item);
|
Add new PDCH UL Controller, drop SBAllocator class
Right now we handle different types of UL allocations in different
classes like PollAllocator and SBAllocator, and they usually don't take
into account the other one in most cases. Furthermore, those objects are
usually per-BTS object, instead of per PDCH object.
This is a first step towards having a unified per-PDCH controller which
takes care of controlling what is scheduled and hence expected on the
uplink. Each PDCH has a UL Controller which keeps track of all reserved
uplink frame, be it SB, RRBP poll or USF assigned, all under the same
API.
As a first step, only the SBA part is fully implemented and used (being
it the easiest part to replace); TBF poll+usf will come in follow-up
patches later on. As a result, the SBAllocator per-BTS class dissappears
but some of its code is refactored/reused to provide more features to the
gprs_rlcmac_sba object, which is also further integrated into the new UL
Controller.
Related: OS#5020
Change-Id: I84b24beea4a1aa2c1528f41435f77bd16df2b947
2021-03-08 13:57:58 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-03-09 16:18:12 +00:00
|
|
|
void pdch_ulc_release_tbf(struct pdch_ulc *ulc, const struct gprs_rlcmac_tbf *tbf)
|
|
|
|
{
|
|
|
|
bool tree_modified;
|
|
|
|
do {
|
|
|
|
struct rb_node *node;
|
|
|
|
struct pdch_ulc_node *item;
|
|
|
|
const struct gprs_rlcmac_tbf *item_tbf;
|
|
|
|
|
|
|
|
tree_modified = false;
|
|
|
|
for (node = rb_first(&ulc->tree_root); node; node = rb_next(node)) {
|
|
|
|
item = container_of(node, struct pdch_ulc_node, node);
|
|
|
|
switch (item->type) {
|
|
|
|
case PDCH_ULC_NODE_SBA:
|
|
|
|
continue;
|
|
|
|
case PDCH_ULC_NODE_TBF_POLL:
|
|
|
|
item_tbf = item->tbf_poll.poll_tbf;
|
|
|
|
break;
|
|
|
|
case PDCH_ULC_NODE_TBF_USF:
|
|
|
|
item_tbf = (struct gprs_rlcmac_tbf *)item->tbf_usf.ul_tbf;
|
|
|
|
break;
|
2021-03-20 15:17:30 +00:00
|
|
|
default:
|
|
|
|
OSMO_ASSERT(0);
|
2021-03-09 16:18:12 +00:00
|
|
|
}
|
|
|
|
if (item_tbf != tbf)
|
|
|
|
continue;
|
|
|
|
/* One entry found, remove it from tree and restart
|
|
|
|
* search from start (to avoid traverse continue from
|
|
|
|
* no-more existant node */
|
|
|
|
tree_modified = true;
|
2021-03-24 13:02:49 +00:00
|
|
|
pdch_ulc_release_node(ulc, item);
|
2021-03-09 16:18:12 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
} while (tree_modified);
|
|
|
|
}
|
|
|
|
|
Add new PDCH UL Controller, drop SBAllocator class
Right now we handle different types of UL allocations in different
classes like PollAllocator and SBAllocator, and they usually don't take
into account the other one in most cases. Furthermore, those objects are
usually per-BTS object, instead of per PDCH object.
This is a first step towards having a unified per-PDCH controller which
takes care of controlling what is scheduled and hence expected on the
uplink. Each PDCH has a UL Controller which keeps track of all reserved
uplink frame, be it SB, RRBP poll or USF assigned, all under the same
API.
As a first step, only the SBA part is fully implemented and used (being
it the easiest part to replace); TBF poll+usf will come in follow-up
patches later on. As a result, the SBAllocator per-BTS class dissappears
but some of its code is refactored/reused to provide more features to the
gprs_rlcmac_sba object, which is also further integrated into the new UL
Controller.
Related: OS#5020
Change-Id: I84b24beea4a1aa2c1528f41435f77bd16df2b947
2021-03-08 13:57:58 +00:00
|
|
|
void pdch_ulc_expire_fn(struct pdch_ulc *ulc, uint32_t fn)
|
|
|
|
{
|
|
|
|
struct gprs_rlcmac_sba *sba;
|
|
|
|
struct pdch_ulc_node *item;
|
2021-03-12 17:24:57 +00:00
|
|
|
int res;
|
Add new PDCH UL Controller, drop SBAllocator class
Right now we handle different types of UL allocations in different
classes like PollAllocator and SBAllocator, and they usually don't take
into account the other one in most cases. Furthermore, those objects are
usually per-BTS object, instead of per PDCH object.
This is a first step towards having a unified per-PDCH controller which
takes care of controlling what is scheduled and hence expected on the
uplink. Each PDCH has a UL Controller which keeps track of all reserved
uplink frame, be it SB, RRBP poll or USF assigned, all under the same
API.
As a first step, only the SBA part is fully implemented and used (being
it the easiest part to replace); TBF poll+usf will come in follow-up
patches later on. As a result, the SBAllocator per-BTS class dissappears
but some of its code is refactored/reused to provide more features to the
gprs_rlcmac_sba object, which is also further integrated into the new UL
Controller.
Related: OS#5020
Change-Id: I84b24beea4a1aa2c1528f41435f77bd16df2b947
2021-03-08 13:57:58 +00:00
|
|
|
|
|
|
|
struct rb_node *first;
|
|
|
|
while((first = rb_first(&ulc->tree_root))) {
|
|
|
|
item = container_of(first, struct pdch_ulc_node, node);
|
2021-03-12 17:24:57 +00:00
|
|
|
res = fn_cmp(item->fn, fn);
|
|
|
|
if (res > 0) /* item->fn AFTER fn */
|
Add new PDCH UL Controller, drop SBAllocator class
Right now we handle different types of UL allocations in different
classes like PollAllocator and SBAllocator, and they usually don't take
into account the other one in most cases. Furthermore, those objects are
usually per-BTS object, instead of per PDCH object.
This is a first step towards having a unified per-PDCH controller which
takes care of controlling what is scheduled and hence expected on the
uplink. Each PDCH has a UL Controller which keeps track of all reserved
uplink frame, be it SB, RRBP poll or USF assigned, all under the same
API.
As a first step, only the SBA part is fully implemented and used (being
it the easiest part to replace); TBF poll+usf will come in follow-up
patches later on. As a result, the SBAllocator per-BTS class dissappears
but some of its code is refactored/reused to provide more features to the
gprs_rlcmac_sba object, which is also further integrated into the new UL
Controller.
Related: OS#5020
Change-Id: I84b24beea4a1aa2c1528f41435f77bd16df2b947
2021-03-08 13:57:58 +00:00
|
|
|
break;
|
2021-03-12 17:24:57 +00:00
|
|
|
if (res < 0) { /* item->fn BEFORE fn */
|
Add new PDCH UL Controller, drop SBAllocator class
Right now we handle different types of UL allocations in different
classes like PollAllocator and SBAllocator, and they usually don't take
into account the other one in most cases. Furthermore, those objects are
usually per-BTS object, instead of per PDCH object.
This is a first step towards having a unified per-PDCH controller which
takes care of controlling what is scheduled and hence expected on the
uplink. Each PDCH has a UL Controller which keeps track of all reserved
uplink frame, be it SB, RRBP poll or USF assigned, all under the same
API.
As a first step, only the SBA part is fully implemented and used (being
it the easiest part to replace); TBF poll+usf will come in follow-up
patches later on. As a result, the SBAllocator per-BTS class dissappears
but some of its code is refactored/reused to provide more features to the
gprs_rlcmac_sba object, which is also further integrated into the new UL
Controller.
Related: OS#5020
Change-Id: I84b24beea4a1aa2c1528f41435f77bd16df2b947
2021-03-08 13:57:58 +00:00
|
|
|
/* Sanity check: */
|
|
|
|
LOGPDCH(ulc->pdch, DRLCMAC, LOGL_ERROR,
|
|
|
|
"Expiring FN=%" PRIu32 " but previous FN=%" PRIu32 " is still reserved!\n",
|
|
|
|
fn, item->fn);
|
|
|
|
}
|
|
|
|
rb_erase(&item->node, &ulc->tree_root);
|
|
|
|
|
|
|
|
switch (item->type) {
|
|
|
|
case PDCH_ULC_NODE_TBF_USF:
|
2021-03-24 13:06:15 +00:00
|
|
|
LOGPDCH(ulc->pdch, DRLCMAC, LOGL_INFO,
|
|
|
|
"Timeout for registered USF (FN=%u): %s\n",
|
|
|
|
item->fn, tbf_name((struct gprs_rlcmac_tbf *)item->tbf_usf.ul_tbf));
|
2021-03-24 13:45:43 +00:00
|
|
|
tbf_usf_timeout(item->tbf_usf.ul_tbf);
|
Add new PDCH UL Controller, drop SBAllocator class
Right now we handle different types of UL allocations in different
classes like PollAllocator and SBAllocator, and they usually don't take
into account the other one in most cases. Furthermore, those objects are
usually per-BTS object, instead of per PDCH object.
This is a first step towards having a unified per-PDCH controller which
takes care of controlling what is scheduled and hence expected on the
uplink. Each PDCH has a UL Controller which keeps track of all reserved
uplink frame, be it SB, RRBP poll or USF assigned, all under the same
API.
As a first step, only the SBA part is fully implemented and used (being
it the easiest part to replace); TBF poll+usf will come in follow-up
patches later on. As a result, the SBAllocator per-BTS class dissappears
but some of its code is refactored/reused to provide more features to the
gprs_rlcmac_sba object, which is also further integrated into the new UL
Controller.
Related: OS#5020
Change-Id: I84b24beea4a1aa2c1528f41435f77bd16df2b947
2021-03-08 13:57:58 +00:00
|
|
|
break;
|
|
|
|
case PDCH_ULC_NODE_TBF_POLL:
|
2021-03-09 16:18:12 +00:00
|
|
|
LOGPDCH(ulc->pdch, DRLCMAC, LOGL_NOTICE,
|
2021-10-12 10:15:45 +00:00
|
|
|
"Timeout for registered POLL (FN=%u, reason=%s): %s\n",
|
|
|
|
item->fn, get_value_string(pdch_ulc_tbf_poll_reason_names, item->tbf_poll.reason),
|
|
|
|
tbf_name(item->tbf_poll.poll_tbf));
|
2021-03-29 17:10:19 +00:00
|
|
|
tbf_poll_timeout(item->tbf_poll.poll_tbf, ulc->pdch, item->fn, item->tbf_poll.reason);
|
Add new PDCH UL Controller, drop SBAllocator class
Right now we handle different types of UL allocations in different
classes like PollAllocator and SBAllocator, and they usually don't take
into account the other one in most cases. Furthermore, those objects are
usually per-BTS object, instead of per PDCH object.
This is a first step towards having a unified per-PDCH controller which
takes care of controlling what is scheduled and hence expected on the
uplink. Each PDCH has a UL Controller which keeps track of all reserved
uplink frame, be it SB, RRBP poll or USF assigned, all under the same
API.
As a first step, only the SBA part is fully implemented and used (being
it the easiest part to replace); TBF poll+usf will come in follow-up
patches later on. As a result, the SBAllocator per-BTS class dissappears
but some of its code is refactored/reused to provide more features to the
gprs_rlcmac_sba object, which is also further integrated into the new UL
Controller.
Related: OS#5020
Change-Id: I84b24beea4a1aa2c1528f41435f77bd16df2b947
2021-03-08 13:57:58 +00:00
|
|
|
break;
|
|
|
|
case PDCH_ULC_NODE_SBA:
|
|
|
|
sba = item->sba.sba;
|
|
|
|
LOGPDCH(sba->pdch, DRLCMAC, LOGL_NOTICE,
|
|
|
|
"Timeout for registered SBA (FN=%u, TA=%u)\n",
|
|
|
|
sba->fn, sba->ta);
|
|
|
|
sba_timeout(sba);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
talloc_free(item);
|
|
|
|
}
|
|
|
|
}
|