diff options
-rw-r--r-- | include/osmo-bts/gsm_data.h | 4 | ||||
-rw-r--r-- | src/common/l1sap.c | 4 | ||||
-rw-r--r-- | src/common/scheduler.c | 14 | ||||
-rw-r--r-- | src/osmo-bts-trx/scheduler_trx.c | 37 | ||||
-rw-r--r-- | src/osmo-bts-trx/trx_if.c | 6 | ||||
-rw-r--r-- | src/osmo-bts-virtual/scheduler_virtbts.c | 18 |
6 files changed, 31 insertions, 52 deletions
diff --git a/include/osmo-bts/gsm_data.h b/include/osmo-bts/gsm_data.h index 416864fb..255c871d 100644 --- a/include/osmo-bts/gsm_data.h +++ b/include/osmo-bts/gsm_data.h @@ -12,6 +12,7 @@ #include <osmocom/codec/ecu.h> #include <osmocom/gsm/lapdm.h> #include <osmocom/gsm/gsm23003.h> +#include <osmocom/gsm/gsm0502.h> #include <osmocom/gsm/gsm_utils.h> #include <osmocom/gsm/tlv.h> #include <osmocom/gsm/rxlev_stat.h> @@ -35,9 +36,6 @@ #define GSM_HR_BYTES 14 /* TS 101318 Chapter 5.2: 112 bits, no sig */ #define GSM_EFR_BYTES 31 /* TS 101318 Chapter 5.3: 244 bits + 4bit sig */ -#define GSM_SUPERFRAME (26*51) /* 1326 TDMA frames */ -#define GSM_HYPERFRAME (2048*GSM_SUPERFRAME) /* GSM_HYPERFRAME frames */ - #define GSM_BTS_AGCH_QUEUE_THRESH_LEVEL_DEFAULT 41 #define GSM_BTS_AGCH_QUEUE_THRESH_LEVEL_DISABLE 999999 #define GSM_BTS_AGCH_QUEUE_LOW_LEVEL_DEFAULT 41 diff --git a/src/common/l1sap.c b/src/common/l1sap.c index dad1b494..17a6c5d4 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -621,7 +621,7 @@ static int l1sap_info_time_ind(struct gsm_bts *bts, /* increment number of RACH slots that have passed by since the * last time indication */ for (i = 0; i < frames_expired; i++) { - uint32_t fn = (info_time_ind->fn + GSM_HYPERFRAME - i) % GSM_HYPERFRAME; + uint32_t fn = GSM_TDMA_FN_SUB(info_time_ind->fn, i); bts->load.rach.total += calc_exprd_rach_frames(bts, fn); } @@ -891,7 +891,7 @@ int32_t bts_get_avg_fn_advance(struct gsm_bts *bts) static void l1sap_update_fnstats(struct gsm_bts *bts, uint32_t rts_fn) { - int32_t delta = (rts_fn + GSM_HYPERFRAME - bts->gsm_time.fn) % GSM_HYPERFRAME; + int32_t delta = GSM_TDMA_FN_SUB(rts_fn, bts->gsm_time.fn); if (delta < bts->fn_stats.min) bts->fn_stats.min = delta; diff --git a/src/common/scheduler.c b/src/common/scheduler.c index 01edc69c..62efed41 100644 --- a/src/common/scheduler.c +++ b/src/common/scheduler.c @@ -684,7 +684,7 @@ struct msgb *_sched_dequeue_prim(struct l1sched_trx *l1t, int8_t tn, uint32_t fn LOGL1S(DL1P, LOGL_ERROR, l1t, tn, chan, fn, "Prim has wrong type.\n"); goto free_msg; } - prim_fn = ((l1sap_fn + GSM_HYPERFRAME - fn) % GSM_HYPERFRAME); + prim_fn = GSM_TDMA_FN_SUB(l1sap_fn, fn); if (prim_fn > 100) { /* l1sap_fn < fn */ LOGL1S(DL1P, LOGL_NOTICE, l1t, tn, chan, fn, "Prim %u is out of range (%u vs exp %u), or channel %s with " @@ -1248,12 +1248,6 @@ no_data: } } -#define TDMA_FN_SUM(a, b) \ - ((a + GSM_HYPERFRAME + b) % GSM_HYPERFRAME) - -#define TDMA_FN_SUB(a, b) \ - ((a + GSM_HYPERFRAME - b) % GSM_HYPERFRAME) - static int trx_sched_calc_frame_loss(struct l1sched_trx *l1t, struct l1sched_chan_state *l1cs, uint8_t tn, uint32_t fn) { @@ -1291,7 +1285,7 @@ static int trx_sched_calc_frame_loss(struct l1sched_trx *l1t, } /* How many frames elapsed since the last one? */ - elapsed_fs = TDMA_FN_SUB(fn, l1cs->last_tdma_fn); + elapsed_fs = GSM_TDMA_FN_SUB(fn, l1cs->last_tdma_fn); if (elapsed_fs > l1ts->mf_period) { /* Too many! */ LOGL1S(DL1P, LOGL_ERROR, l1t, tn, frame_head->ul_chan, fn, "Too many (>%u) contiguous TDMA frames=%u elapsed " @@ -1310,7 +1304,7 @@ static int trx_sched_calc_frame_loss(struct l1sched_trx *l1t, * Start counting from the last_fn + 1. */ for (i = 1; i < elapsed_fs; i++) { - fn_i = TDMA_FN_SUM(l1cs->last_tdma_fn, i); + fn_i = GSM_TDMA_FN_SUM(l1cs->last_tdma_fn, i); offset = fn_i % l1ts->mf_period; frame = l1ts->mf_frames + offset; @@ -1343,7 +1337,7 @@ static int trx_sched_calc_frame_loss(struct l1sched_trx *l1t, }; for (i = 1; i < elapsed_fs; i++) { - fn_i = TDMA_FN_SUM(l1cs->last_tdma_fn, i); + fn_i = GSM_TDMA_FN_SUM(l1cs->last_tdma_fn, i); offset = fn_i % l1ts->mf_period; frame = l1ts->mf_frames + offset; func = trx_chan_desc[frame->ul_chan].ul_fn; diff --git a/src/osmo-bts-trx/scheduler_trx.c b/src/osmo-bts-trx/scheduler_trx.c index d4a38b61..3936124c 100644 --- a/src/osmo-bts-trx/scheduler_trx.c +++ b/src/osmo-bts-trx/scheduler_trx.c @@ -74,7 +74,7 @@ static int trx_sched_fn(struct gsm_bts *bts, uint32_t fn) /* advance frame number, so the transceiver has more * time until it must be transmitted. */ - fn = (fn + plink->u.osmotrx.clock_advance) % GSM_HYPERFRAME; + fn = GSM_TDMA_FN_SUM(fn, plink->u.osmotrx.clock_advance); /* we don't schedule, if power is off */ if (!trx_if_powered(l1h)) @@ -83,8 +83,7 @@ static int trx_sched_fn(struct gsm_bts *bts, uint32_t fn) /* process every TS of TRX */ for (tn = 0; tn < ARRAY_SIZE(l1t->ts); tn++) { /* ready-to-send */ - _sched_rts(l1t, tn, - (fn + plink->u.osmotrx.rts_advance) % GSM_HYPERFRAME); + _sched_rts(l1t, tn, GSM_TDMA_FN_SUM(fn, plink->u.osmotrx.rts_advance)); /* All other parameters to be set by _sched_dl_burst() */ br = (struct trx_dl_burst_req) { @@ -105,10 +104,6 @@ static int trx_sched_fn(struct gsm_bts *bts, uint32_t fn) return 0; } -/*! duration of a GSM frame in nano-seconds. (120ms/26) */ -#define FRAME_DURATION_nS 4615384 -/*! duration of a GSM frame in micro-seconds (120s/26) */ -#define FRAME_DURATION_uS (FRAME_DURATION_nS/1000) /*! maximum number of 'missed' frame periods we can tolerate of OS doesn't schedule us*/ #define MAX_FN_SKEW 50 /*! maximum number of frame periods we can tolerate without TRX Clock Indication*/ @@ -126,9 +121,9 @@ static inline int64_t compute_elapsed_us(const struct timespec *last, const stru /*! compute the number of frame number intervals elapsed between \a last and \a now */ static inline int compute_elapsed_fn(const uint32_t last, const uint32_t now) { - int elapsed_fn = (now + GSM_HYPERFRAME - last) % GSM_HYPERFRAME; + int elapsed_fn = GSM_TDMA_FN_SUB(now, last); if (elapsed_fn >= 135774) - elapsed_fn -= GSM_HYPERFRAME; + elapsed_fn -= GSM_TDMA_HYPERFRAME; return elapsed_fn; } @@ -139,9 +134,6 @@ static inline void normalize_timespec(struct timespec *ts) ts->tv_nsec = ts->tv_nsec % 1000000000; } -/*! Increment a GSM frame number modulo GSM_HYPERFRAME */ -#define INCREMENT_FN(fn) (fn) = (((fn) + 1) % GSM_HYPERFRAME) - extern int quit; /*! this is the timerfd-callback firing for every FN to be processed */ @@ -178,7 +170,7 @@ static int trx_fn_timer_cb(struct osmo_fd *ofd, unsigned int what) /* compute actual elapsed time and resulting OS scheduling error */ clock_gettime(CLOCK_MONOTONIC, &tv_now); elapsed_us = compute_elapsed_us(&tcs->last_fn_timer.tv, &tv_now); - error_us = elapsed_us - FRAME_DURATION_uS; + error_us = elapsed_us - GSM_TDMA_FN_DURATION_uS; #ifdef DEBUG_CLOCK printf("%s(): %09ld, elapsed_us=%05" PRId64 ", error_us=%-d: fn=%d\n", __func__, tv_now.tv_nsec, elapsed_us, error_us, tcs->last_fn_timer.fn+1); @@ -186,17 +178,15 @@ static int trx_fn_timer_cb(struct osmo_fd *ofd, unsigned int what) tcs->last_fn_timer.tv = tv_now; /* if someone played with clock, or if the process stalled */ - if (elapsed_us > FRAME_DURATION_uS * MAX_FN_SKEW || elapsed_us < 0) { + if (elapsed_us > GSM_TDMA_FN_DURATION_uS * MAX_FN_SKEW || elapsed_us < 0) { LOGP(DL1C, LOGL_ERROR, "PC clock skew: elapsed_us=%" PRId64 ", error_us=%" PRId64 "\n", elapsed_us, error_us); goto no_clock; } /* call trx_sched_fn() for all expired FN */ - for (i = 0; i < expire_count; i++) { - INCREMENT_FN(tcs->last_fn_timer.fn); - trx_sched_fn(bts, tcs->last_fn_timer.fn); - } + for (i = 0; i < expire_count; i++) + trx_sched_fn(bts, GSM_TDMA_FN_INC(tcs->last_fn_timer.fn)); return 0; @@ -281,7 +271,7 @@ int trx_sched_clock(struct gsm_bts *bts, uint32_t fn) int elapsed_fn; int64_t elapsed_us, elapsed_us_since_clk, elapsed_fn_since_clk, error_us_since_clk; unsigned int fn_caught_up = 0; - const struct timespec interval = { .tv_sec = 0, .tv_nsec = FRAME_DURATION_nS }; + const struct timespec interval = { .tv_sec = 0, .tv_nsec = GSM_TDMA_FN_DURATION_nS }; if (quit) return 0; @@ -307,7 +297,7 @@ int trx_sched_clock(struct gsm_bts *bts, uint32_t fn) elapsed_us_since_clk = compute_elapsed_us(&tcs->last_clk_ind.tv, &tv_now); elapsed_fn_since_clk = compute_elapsed_fn(tcs->last_clk_ind.fn, fn); /* error (delta) between local clock since last CLK and CLK based on FN clock at TRX */ - error_us_since_clk = elapsed_us_since_clk - (FRAME_DURATION_uS * elapsed_fn_since_clk); + error_us_since_clk = elapsed_us_since_clk - (GSM_TDMA_FN_DURATION_uS * elapsed_fn_since_clk); LOGP(DL1C, LOGL_INFO, "TRX Clock Ind: elapsed_us=%7"PRId64", " "elapsed_fn=%3"PRId64", error_us=%+5"PRId64"\n", elapsed_us_since_clk, elapsed_fn_since_clk, error_us_since_clk); @@ -328,14 +318,14 @@ int trx_sched_clock(struct gsm_bts *bts, uint32_t fn) } LOGP(DL1C, LOGL_INFO, "GSM clock jitter: %" PRId64 "us (elapsed_fn=%d)\n", - elapsed_fn * FRAME_DURATION_uS - elapsed_us, elapsed_fn); + elapsed_fn * GSM_TDMA_FN_DURATION_uS - elapsed_us, elapsed_fn); /* too many frames have been processed already */ if (elapsed_fn < 0) { struct timespec first = interval; /* set clock to the time or last FN should have been * transmitted. */ - first.tv_nsec += (0 - elapsed_fn) * FRAME_DURATION_nS; + first.tv_nsec += (0 - elapsed_fn) * GSM_TDMA_FN_DURATION_nS; normalize_timespec(&first); LOGP(DL1C, LOGL_NOTICE, "We were %d FN faster than TRX, compensating\n", -elapsed_fn); /* set time to the time our next FN has to be transmitted */ @@ -345,8 +335,7 @@ int trx_sched_clock(struct gsm_bts *bts, uint32_t fn) /* transmit what we still need to transmit */ while (fn != tcs->last_fn_timer.fn) { - INCREMENT_FN(tcs->last_fn_timer.fn); - trx_sched_fn(bts, tcs->last_fn_timer.fn); + trx_sched_fn(bts, GSM_TDMA_FN_INC(tcs->last_fn_timer.fn)); fn_caught_up++; } diff --git a/src/osmo-bts-trx/trx_if.c b/src/osmo-bts-trx/trx_if.c index 6fe0ecd6..58f74553 100644 --- a/src/osmo-bts-trx/trx_if.c +++ b/src/osmo-bts-trx/trx_if.c @@ -121,8 +121,8 @@ static int trx_clk_read_cb(struct osmo_fd *ofd, unsigned int what) LOGPPHI(pinst, DTRX, LOGL_INFO, "Clock indication: fn=%u\n", fn); - if (fn >= GSM_HYPERFRAME) { - fn %= GSM_HYPERFRAME; + if (fn >= GSM_TDMA_HYPERFRAME) { + fn %= GSM_TDMA_HYPERFRAME; LOGPPHI(pinst, DTRX, LOGL_ERROR, "Indicated clock's FN is not " "wrapping correctly, correcting to fn=%u\n", fn); } @@ -737,7 +737,7 @@ static int trx_data_handle_hdr_v0(struct trx_l1h *l1h, bi->rssi = -(int8_t)buf[5]; bi->toa256 = (int16_t) osmo_load16be(buf + 6); - if (bi->fn >= GSM_HYPERFRAME) { + if (bi->fn >= GSM_TDMA_HYPERFRAME) { LOGPPHI(l1h->phy_inst, DTRX, LOGL_ERROR, "Illegal TDMA fn=%u\n", bi->fn); return -EINVAL; diff --git a/src/osmo-bts-virtual/scheduler_virtbts.c b/src/osmo-bts-virtual/scheduler_virtbts.c index d3fdf1ab..1c2b057e 100644 --- a/src/osmo-bts-virtual/scheduler_virtbts.c +++ b/src/osmo-bts-virtual/scheduler_virtbts.c @@ -532,7 +532,6 @@ void _sched_act_rach_det(struct l1sched_trx *l1t, uint8_t tn, uint8_t ss, int ac ***********************************************************************/ #define RTS_ADVANCE 5 /* about 20ms */ -#define FRAME_DURATION_uS 4615 static int vbts_sched_fn(struct gsm_bts *bts, uint32_t fn) { @@ -558,7 +557,7 @@ static int vbts_sched_fn(struct gsm_bts *bts, uint32_t fn) * --> Handle and process non-transparent RSL-Messages (activate channel, ) * --> Forward transparent RSL-DATA-Messages to the ms by appending them to * the l1-dl-queue */ - _sched_rts(l1t, br.tn, (fn + RTS_ADVANCE) % GSM_HYPERFRAME); + _sched_rts(l1t, br.tn, GSM_TDMA_FN_SUM(fn, RTS_ADVANCE)); /* schedule transmit backend functions */ /* Process data in the l1-dlqueue and forward it * to MS */ @@ -587,28 +586,27 @@ static void vbts_fn_timer_cb(void *data) + (tv_now.tv_usec - tv_clock->tv_usec); /* not so good somehow a lot of time passed between two timer callbacks */ - if (elapsed_us > 2 *FRAME_DURATION_uS) + if (elapsed_us > 2 *GSM_TDMA_FN_DURATION_uS) LOGP(DL1P, LOGL_NOTICE, "vbts_fn_timer_cb after %d us\n", elapsed_us); /* schedule the current frame/s (fn = frame number) * this loop will be called at least once, but can also be executed * multiple times if more than one frame duration (4615us) passed till the last callback */ - while (elapsed_us > FRAME_DURATION_uS / 2) { + while (elapsed_us > GSM_TDMA_FN_DURATION_uS / 2) { const struct timeval tv_frame = { .tv_sec = 0, - .tv_usec = FRAME_DURATION_uS, + .tv_usec = GSM_TDMA_FN_DURATION_uS, }; timeradd(tv_clock, &tv_frame, tv_clock); /* increment the frame number in the BTS model instance */ - bts_virt->last_fn = (bts_virt->last_fn + 1) % GSM_HYPERFRAME; - vbts_sched_fn(bts, bts_virt->last_fn); - elapsed_us -= FRAME_DURATION_uS; + vbts_sched_fn(bts, GSM_TDMA_FN_INC(bts_virt->last_fn)); + elapsed_us -= GSM_TDMA_FN_DURATION_uS; } /* re-schedule the timer */ /* timer is set to frame duration - elapsed time to guarantee that this cb method will be * periodically executed every 4.615ms */ - osmo_timer_schedule(&bts_virt->fn_timer, 0, FRAME_DURATION_uS - elapsed_us); + osmo_timer_schedule(&bts_virt->fn_timer, 0, GSM_TDMA_FN_DURATION_uS - elapsed_us); } int vbts_sched_start(struct gsm_bts *bts) @@ -622,7 +620,7 @@ int vbts_sched_start(struct gsm_bts *bts) gettimeofday(&bts_virt->tv_clock, NULL); /* trigger the first timer after 4615us (a frame duration) */ - osmo_timer_schedule(&bts_virt->fn_timer, 0, FRAME_DURATION_uS); + osmo_timer_schedule(&bts_virt->fn_timer, 0, GSM_TDMA_FN_DURATION_uS); return 0; } |