osmo-bts-trx/scheduler: refactor dummy burst scheduling
This change facilitates the upcoming freq. hopping implementation, in particular scheduling of dummy bursts on C0 with hopping time- slots. One problem is that we cannot know in advance, whether to send a dummy burst on a given timeslot unless all transceivers are processed. For example, trx#3 may want to send a normal burst on ARFCN of trx#0 (C0), while we have already sent a dummy burst... Another important aspect is that we shall not be sending dummy bursts on transceivers other than C0. Scheduling dummy bursts from _sched_dl_burst() in the context of a single hopping timeslot of a single transceiver leaves trx_sched_fn() no way to know whether it's a dummy burst or something else. Let's solve both problems by moving dummy burst scheduling logic from _sched_dl_burst() to trx_sched_fn(). Maintain C0 slot-mask in the inner (per-trx) loop, so that we can fill missing bursts with dummy bursts afterwards. Change-Id: I8c3651c27d2991079e83b8abdb7e2c3f95b97a43 Related: SYS#4868, OS#4546
This commit is contained in:
parent
9d5e955ea1
commit
10e64630ce
|
@ -35,6 +35,7 @@ struct trx_chan_desc {
|
|||
};
|
||||
extern const struct trx_chan_desc trx_chan_desc[_TRX_CHAN_MAX];
|
||||
|
||||
extern const ubit_t _sched_dummy_burst[];
|
||||
extern const ubit_t _sched_tsc[8][26];
|
||||
extern const ubit_t _sched_egprs_tsc[8][78];
|
||||
extern const ubit_t _sched_sch_train[64];
|
||||
|
|
|
@ -52,8 +52,9 @@ static int rts_tchf_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,
|
|||
enum trx_chan_type chan);
|
||||
static int rts_tchh_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,
|
||||
enum trx_chan_type chan);
|
||||
|
||||
/*! \brief Dummy Burst (TS 05.02 Chapter 5.2.6) */
|
||||
static const ubit_t dummy_burst[GSM_BURST_LEN] = {
|
||||
const ubit_t _sched_dummy_burst[GSM_BURST_LEN] = {
|
||||
0,0,0,
|
||||
1,1,1,1,1,0,1,1,0,1,1,1,0,1,1,0,0,0,0,0,1,0,1,0,0,1,0,0,1,1,1,0,
|
||||
0,0,0,0,1,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,1,1,1,0,0,
|
||||
|
@ -1189,7 +1190,7 @@ void _sched_dl_burst(struct l1sched_trx *l1t, struct trx_dl_burst_req *br)
|
|||
enum trx_chan_type chan;
|
||||
|
||||
if (!l1ts->mf_index)
|
||||
goto no_data;
|
||||
return;
|
||||
|
||||
/* get frame from multiframe */
|
||||
period = l1ts->mf_period;
|
||||
|
@ -1204,11 +1205,11 @@ void _sched_dl_burst(struct l1sched_trx *l1t, struct trx_dl_burst_req *br)
|
|||
|
||||
/* check if channel is active */
|
||||
if (!TRX_CHAN_IS_ACTIVE(l1cs, chan))
|
||||
goto no_data;
|
||||
return;
|
||||
|
||||
/* get burst from function */
|
||||
if (func(l1t, chan, bid, br) != 0)
|
||||
goto no_data;
|
||||
return;
|
||||
|
||||
/* BS Power reduction (in dB) per logical channel */
|
||||
if (l1cs->lchan != NULL)
|
||||
|
@ -1225,19 +1226,6 @@ void _sched_dl_burst(struct l1sched_trx *l1t, struct trx_dl_burst_req *br)
|
|||
br->burst[i + 88] ^= ks[i + 57];
|
||||
}
|
||||
}
|
||||
|
||||
no_data:
|
||||
/* in case of C0, we need a dummy burst to maintain RF power */
|
||||
if (!br->burst_len && l1t->trx == l1t->trx->bts->c0) {
|
||||
#if 0
|
||||
if (chan != TRXC_IDLE) // hack
|
||||
LOGP(DL1C, LOGL_DEBUG, "No burst data for %s fn=%u ts=%u "
|
||||
"burst=%d on C0, so filling with dummy burst\n",
|
||||
trx_chan_desc[chan].name, fn, tn, bid);
|
||||
#endif
|
||||
memcpy(br->burst, dummy_burst, ARRAY_SIZE(dummy_burst));
|
||||
br->burst_len = ARRAY_SIZE(dummy_burst);
|
||||
}
|
||||
}
|
||||
|
||||
static int trx_sched_calc_frame_loss(struct l1sched_trx *l1t,
|
||||
|
|
|
@ -60,6 +60,7 @@ static void trx_sched_fn(struct gsm_bts *bts, const uint32_t fn)
|
|||
{
|
||||
struct trx_dl_burst_req br;
|
||||
struct gsm_bts_trx *trx;
|
||||
uint8_t c0_mask = 0x00;
|
||||
uint32_t sched_fn;
|
||||
uint8_t tn;
|
||||
|
||||
|
@ -99,9 +100,31 @@ static void trx_sched_fn(struct gsm_bts *bts, const uint32_t fn)
|
|||
continue;
|
||||
}
|
||||
|
||||
/* update dummy burst mask for C0 */
|
||||
if (trx == bts->c0)
|
||||
c0_mask |= (1 << tn);
|
||||
|
||||
trx_if_send_burst(l1h, &br);
|
||||
}
|
||||
}
|
||||
|
||||
/* send dummy bursts on inactive timeslots of C0 */
|
||||
struct phy_instance *pinst = trx_phy_instance(bts->c0);
|
||||
struct trx_l1h *l1h = pinst->u.osmotrx.hdl;
|
||||
struct phy_link *plink = pinst->phy_link;
|
||||
|
||||
br = (struct trx_dl_burst_req) {
|
||||
.fn = GSM_TDMA_FN_SUM(fn, plink->u.osmotrx.clock_advance),
|
||||
.burst_len = GSM_BURST_LEN,
|
||||
};
|
||||
|
||||
memcpy(br.burst, _sched_dummy_burst, GSM_BURST_LEN);
|
||||
|
||||
for (br.tn = 0; br.tn < TRX_NR_TS; br.tn++) {
|
||||
if (c0_mask & (1 << br.tn))
|
||||
continue;
|
||||
trx_if_send_burst(l1h, &br);
|
||||
}
|
||||
}
|
||||
|
||||
/*! maximum number of 'missed' frame periods we can tolerate of OS doesn't schedule us*/
|
||||
|
|
Loading…
Reference in New Issue