pespin has submitted this change. ( https://gerrit.osmocom.org/c/osmocom-bb/+/34139 )
Change subject: trxcon: properly handle PDCH slotmask in UL/DL TBF CFG.Req ......................................................................
trxcon: properly handle PDCH slotmask in UL/DL TBF CFG.Req
Change-Id: I4c2ff25217fba0b6b4704f023071b86ed9afb55c Related: OS#5500 --- M include/l1gprs.h M src/host/trxcon/src/trxcon_fsm.c M src/shared/l1gprs.c 3 files changed, 74 insertions(+), 0 deletions(-)
Approvals: Jenkins Builder: Verified fixeria: Looks good to me, but someone else must approve osmith: Looks good to me, but someone else must approve pespin: Looks good to me, approved
diff --git a/include/l1gprs.h b/include/l1gprs.h index bbd654d..060366e 100644 --- a/include/l1gprs.h +++ b/include/l1gprs.h @@ -2,6 +2,7 @@
#include <stdint.h> #include <stdbool.h> +#include <stddef.h>
#include <osmocom/core/linuxlist.h>
@@ -34,6 +35,14 @@ uint32_t dl_tfi_mask; };
+static inline size_t l1gprs_pdch_use_count(const struct l1gprs_pdch *pdch) +{ + return pdch->ul_tbf_count + pdch->dl_tbf_count; +} + + +typedef void (*l1gprs_pdch_changed_t)(struct l1gprs_pdch *pdch, bool active); + struct l1gprs_state { /*! PDCH state for each timeslot */ struct l1gprs_pdch pdch[8]; @@ -43,11 +52,14 @@ char *log_prefix; /*! Some private data for API user */ void *priv; + /*! Callback triggered to signal lower layers when a PDCH TS has to be activated/deactivated */ + l1gprs_pdch_changed_t pdch_changed_cb; };
void l1gprs_logging_init(int logc); struct l1gprs_state *l1gprs_state_alloc(void *ctx, const char *log_prefix, void *priv); void l1gprs_state_free(struct l1gprs_state *gprs); +void l1gprs_state_set_pdch_changed_cb(struct l1gprs_state *gprs, l1gprs_pdch_changed_t pdch_changed_cb);
int l1gprs_handle_ul_tbf_cfg_req(struct l1gprs_state *gprs, const struct msgb *msg); int l1gprs_handle_dl_tbf_cfg_req(struct l1gprs_state *gprs, const struct msgb *msg); diff --git a/src/host/trxcon/src/trxcon_fsm.c b/src/host/trxcon/src/trxcon_fsm.c index eabab3d..e7c60f2 100644 --- a/src/host/trxcon/src/trxcon_fsm.c +++ b/src/host/trxcon/src/trxcon_fsm.c @@ -517,6 +517,30 @@ } }
+static void handle_tbf_cfg_req(struct trxcon_inst *trxcon, uint8_t tn, bool active) +{ + struct l1sched_state *sched = trxcon->sched; + + if (active) { + if (sched->ts[tn] != NULL) /* already enabled */ + return; + if (l1sched_configure_ts(sched, tn, GSM_PCHAN_PDCH) != 0) + return; + OSMO_ASSERT(sched->ts[tn] != NULL); + + l1sched_activate_lchan(sched->ts[tn], L1SCHED_PDTCH); + l1sched_activate_lchan(sched->ts[tn], L1SCHED_PTCCH); + /* FIXME: set TSC for both lchans */ + } else { + l1sched_del_ts(sched, tn); + } +} + +static void trxcon_l1gprs_state_changed_cb(struct l1gprs_pdch *pdch, bool active) +{ + handle_tbf_cfg_req(pdch->gprs->priv, pdch->tn, active); +} + static void trxcon_st_packet_data_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) { @@ -524,6 +548,7 @@
OSMO_ASSERT(trxcon->gprs == NULL); trxcon->gprs = l1gprs_state_alloc(trxcon, trxcon->log_prefix, trxcon); + l1gprs_state_set_pdch_changed_cb(trxcon->gprs, trxcon_l1gprs_state_changed_cb); OSMO_ASSERT(trxcon->gprs != NULL); }
diff --git a/src/shared/l1gprs.c b/src/shared/l1gprs.c index 1c3dba8..bae13d2 100644 --- a/src/shared/l1gprs.c +++ b/src/shared/l1gprs.c @@ -118,6 +118,12 @@ LOGP_PDCH(pdch, LOGL_DEBUG, "Linked " LOG_TBF_FMT "\n", LOG_TBF_ARGS(tbf)); + + /* If just got first use: */ + if (l1gprs_pdch_use_count(pdch) == 1) { + if (gprs->pdch_changed_cb) + gprs->pdch_changed_cb(pdch, true); + } }
llist_add_tail(&tbf->list, &gprs->tbf_list); @@ -154,6 +160,11 @@ } LOGP_PDCH(pdch, LOGL_DEBUG, "Unlinked " LOG_TBF_FMT "\n", LOG_TBF_ARGS(tbf)); + /* If not more in use: */ + if (l1gprs_pdch_use_count(pdch) == 0) { + if (gprs->pdch_changed_cb) + gprs->pdch_changed_cb(pdch, false); + } } else { /* Slot was not set, add it */ if (tbf->uplink) { @@ -164,6 +175,11 @@ } LOGP_PDCH(pdch, LOGL_DEBUG, "Linked " LOG_TBF_FMT "\n", LOG_TBF_ARGS(tbf)); + /* If just got first use: */ + if (l1gprs_pdch_use_count(pdch) == 1) { + if (gprs->pdch_changed_cb) + gprs->pdch_changed_cb(pdch, true); + } } }
@@ -197,6 +213,12 @@ LOGP_PDCH(pdch, LOGL_DEBUG, "Unlinked " LOG_TBF_FMT "\n", LOG_TBF_ARGS(tbf)); + + /* If not more in use: */ + if (l1gprs_pdch_use_count(pdch) == 0) { + if (gprs->pdch_changed_cb) + gprs->pdch_changed_cb(pdch, false); + } }
LOGP_GPRS(gprs, LOGL_INFO, @@ -309,6 +331,11 @@ talloc_free(gprs); }
+void l1gprs_state_set_pdch_changed_cb(struct l1gprs_state *gprs, l1gprs_pdch_changed_t pdch_changed_cb) +{ + gprs->pdch_changed_cb = pdch_changed_cb; +} + int l1gprs_handle_ul_tbf_cfg_req(struct l1gprs_state *gprs, const struct msgb *msg) { const struct l1ctl_gprs_ul_tbf_cfg_req *req = (void *)msg->l1h;