aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@netfilter.org>2009-08-10 13:46:55 +0200
committerHarald Welte <laforge@netfilter.org>2009-08-10 13:46:55 +0200
commitfc0d9526024d14f7c9ab8ad17d428fe0b7e21a25 (patch)
tree60321920bb365220c2f24c20f7c5e287749a680f
parent88367263486c4866272cd3d57c76097793aba654 (diff)
introduce bts->chan_alloc_reverse flag
The channel allocator can be set in ascending or descending order. Ascnending means we first try to allocate channels on TRX0, then TRX1, etc. Descending means we first try to allocate cahnnels on TRXn, then n-1 down to 0.
-rw-r--r--openbsc/include/openbsc/gsm_data.h4
-rw-r--r--openbsc/src/chan_alloc.c55
2 files changed, 42 insertions, 17 deletions
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index 81de84f71..e995c1751 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -298,6 +298,10 @@ struct gsm_bts {
/* type of BTS */
enum gsm_bts_type type;
enum gsm_band band;
+ /* should the channel allocator allocate channels from high TRX to TRX0,
+ * rather than starting from TRX0 and go upwards? */
+ int chan_alloc_reverse;
+
/* how do we talk OML with this TRX? */
struct gsm_e1_subslot oml_e1_link;
u_int8_t oml_tei;
diff --git a/openbsc/src/chan_alloc.c b/openbsc/src/chan_alloc.c
index dd04c3e25..0cf567f8e 100644
--- a/openbsc/src/chan_alloc.c
+++ b/openbsc/src/chan_alloc.c
@@ -124,25 +124,46 @@ static const u_int8_t subslots_per_pchan[] = {
};
static struct gsm_lchan *
-_lc_find(struct gsm_bts *bts, enum gsm_phys_chan_config pchan)
+_lc_find_trx(struct gsm_bts_trx *trx, enum gsm_phys_chan_config pchan)
{
- struct gsm_bts_trx *trx;
struct gsm_bts_trx_ts *ts;
int j, ss;
- llist_for_each_entry(trx, &bts->trx_list, list) {
- for (j = 0; j < 8; j++) {
- ts = &trx->ts[j];
- if (ts->pchan != pchan)
- continue;
- /* check if all sub-slots are allocated yet */
- for (ss = 0; ss < subslots_per_pchan[pchan]; ss++) {
- struct gsm_lchan *lc = &ts->lchan[ss];
- if (lc->type == GSM_LCHAN_NONE)
- return lc;
- }
+ for (j = 0; j < 8; j++) {
+ ts = &trx->ts[j];
+ if (ts->pchan != pchan)
+ continue;
+ /* check if all sub-slots are allocated yet */
+ for (ss = 0; ss < subslots_per_pchan[pchan]; ss++) {
+ struct gsm_lchan *lc = &ts->lchan[ss];
+ if (lc->type == GSM_LCHAN_NONE)
+ return lc;
}
}
+ return NULL;
+}
+
+static struct gsm_lchan *
+_lc_find_bts(struct gsm_bts *bts, enum gsm_phys_chan_config pchan)
+{
+ struct gsm_bts_trx *trx;
+ struct gsm_bts_trx_ts *ts;
+ struct gsm_lchan *lc;
+
+ if (bts->chan_alloc_reverse) {
+ llist_for_each_entry_reverse(trx, &bts->trx_list, list) {
+ lc = _lc_find_trx(trx, pchan);
+ if (lc)
+ return lc;
+ }
+ } else {
+ llist_for_each_entry(trx, &bts->trx_list, list) {
+ lc = _lc_find_trx(trx, pchan);
+ if (lc)
+ return lc;
+ }
+ }
+
/* we cannot allocate more of these */
if (pchan == GSM_PCHAN_CCCH_SDCCH4)
return NULL;
@@ -164,15 +185,15 @@ struct gsm_lchan *lchan_alloc(struct gsm_bts *bts, enum gsm_chan_t type)
switch (type) {
case GSM_LCHAN_SDCCH:
- lchan = _lc_find(bts, GSM_PCHAN_CCCH_SDCCH4);
+ lchan = _lc_find_bts(bts, GSM_PCHAN_CCCH_SDCCH4);
if (lchan == NULL)
- lchan = _lc_find(bts, GSM_PCHAN_SDCCH8_SACCH8C);
+ lchan = _lc_find_bts(bts, GSM_PCHAN_SDCCH8_SACCH8C);
break;
case GSM_LCHAN_TCH_F:
- lchan = _lc_find(bts, GSM_PCHAN_TCH_F);
+ lchan = _lc_find_bts(bts, GSM_PCHAN_TCH_F);
break;
case GSM_LCHAN_TCH_H:
- lchan =_lc_find(bts, GSM_PCHAN_TCH_H);
+ lchan =_lc_find_bts(bts, GSM_PCHAN_TCH_H);
break;
default:
fprintf(stderr, "Unknown gsm_chan_t %u\n", type);