Review at https://gerrit.osmocom.org/6774
host/trxcon/l1ctl.c: share primitive management code This change introduces shared primitive management functions, exposed from the l1ctl_rx_data_req() implementation: - sched_trx_init_prim() - allocates memory for a new primitive and its payload. Initializes primitive's header, setting the logical channel type and the payload length. After initialization, the talloc context of a primitive is a trx instance, which passed as the first argument. - sched_trx_push_prim() - decodes the timeslot index from chan_nr and pushes a primitive to its transimt queue. The talloc context of primitive is changed to the parent trx_ts instance after queuing. Both functions will be used for handling both L1CTL_TRAFFIC_REQ and L1CTL_RACH_REQ. Change-Id: I8169a1ef4ef54d91b50f3e213e4842f54af8b499 --- M src/host/trxcon/l1ctl.c M src/host/trxcon/sched_trx.c M src/host/trxcon/sched_trx.h 3 files changed, 92 insertions(+), 46 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmocom-bb refs/changes/74/6774/1 diff --git a/src/host/trxcon/l1ctl.c b/src/host/trxcon/l1ctl.c index f193a7a..f125948 100644 --- a/src/host/trxcon/l1ctl.c +++ b/src/host/trxcon/l1ctl.c @@ -589,17 +589,13 @@ static int l1ctl_rx_data_req(struct l1ctl_link *l1l, struct msgb *msg) { - struct trx_ts *ts; - struct trx_ts_prim *prim; struct l1ctl_info_ul *ul; - struct l1ctl_data_ind *data_ind; - enum trx_lchan_type lchan_type; - uint8_t chan_nr, link_id, tn; - size_t len; - int rc = 0; + struct trx_ts_prim *prim; + uint8_t chan_nr, link_id; + int rc; + /* Extract UL frame header */ ul = (struct l1ctl_info_ul *) msg->l1h; - data_ind = (struct l1ctl_data_ind *) ul->payload; /* Obtain channel description */ chan_nr = ul->chan_nr; @@ -608,48 +604,21 @@ LOGP(DL1D, LOGL_DEBUG, "Recv Data Req (chan_nr=0x%02x, " "link_id=0x%02x)\n", chan_nr, link_id); - /* Determine TS index */ - tn = chan_nr & 0x7; - if (tn > 7) { - LOGP(DL1D, LOGL_ERROR, "Incorrect TS index %u\n", tn); - rc = -EINVAL; + /* Init a new primitive */ + rc = sched_trx_init_prim(l1l->trx, &prim, 23, + chan_nr, link_id); + if (rc) + goto exit; + + /* Push this primitive to transmit queue */ + rc = sched_trx_push_prim(l1l->trx, prim, chan_nr); + if (rc) { + talloc_free(prim); goto exit; } - - /* Determine lchan type */ - lchan_type = sched_trx_chan_nr2lchan_type(chan_nr, link_id); - if (!lchan_type) { - LOGP(DL1D, LOGL_ERROR, "Couldn't determine lchan type " - "for chan_nr=%02x and link_id=%02x\n", chan_nr, link_id); - rc = -EINVAL; - goto exit; - } - - /* Check whether required timeslot is allocated and configured */ - ts = l1l->trx->ts_list[tn]; - if (ts == NULL || ts->mf_layout == NULL) { - LOGP(DL1D, LOGL_ERROR, "Timeslot %u isn't configured\n", tn); - rc = -EINVAL; - goto exit; - } - - /* Allocate a new primitive */ - len = sizeof(struct trx_ts_prim) + sizeof(struct l1ctl_info_ul) + 23; - prim = talloc_zero_size(ts, len); - if (prim == NULL) { - LOGP(DL1D, LOGL_ERROR, "Failed to allocate memory\n"); - rc = -ENOMEM; - goto exit; - } - - /* Set logical channel of primitive */ - prim->chan = lchan_type; /* Fill in the payload */ - memcpy(prim->payload, data_ind, 23); - - /* Add to TS queue */ - llist_add_tail(&prim->list, &ts->tx_prims); + memcpy(prim->payload, ul->payload, 23); exit: msgb_free(msg); diff --git a/src/host/trxcon/sched_trx.c b/src/host/trxcon/sched_trx.c index 956c261..7f6729c 100644 --- a/src/host/trxcon/sched_trx.c +++ b/src/host/trxcon/sched_trx.c @@ -417,6 +417,75 @@ } } +int sched_trx_init_prim(struct trx_instance *trx, + struct trx_ts_prim **prim, size_t pl_len, + uint8_t chan_nr, uint8_t link_id) +{ + enum trx_lchan_type lchan_type; + struct trx_ts_prim *new_prim; + uint8_t len; + + /* Determine lchan type */ + lchan_type = sched_trx_chan_nr2lchan_type(chan_nr, link_id); + if (!lchan_type) { + LOGP(DSCH, LOGL_ERROR, "Couldn't determine lchan type " + "for chan_nr=%02x and link_id=%02x\n", chan_nr, link_id); + return -EINVAL; + } + + /* How much memory do we need? */ + len = sizeof(struct trx_ts_prim); /* Primitive header */ + len += pl_len; /* Requested payload size */ + + /* Allocate a new primitive */ + new_prim = talloc_zero_size(trx, len); + if (new_prim == NULL) { + LOGP(DSCH, LOGL_ERROR, "Failed to allocate memory\n"); + return -ENOMEM; + } + + /* Init primitive header */ + new_prim->payload_len = pl_len; + new_prim->chan = lchan_type; + + /* Set external pointer */ + *prim = new_prim; + + return 0; +} + +int sched_trx_push_prim(struct trx_instance *trx, + struct trx_ts_prim *prim, uint8_t chan_nr) +{ + struct trx_ts *ts; + uint8_t tn; + + /* Determine TS index */ + tn = chan_nr & 0x7; + if (tn > 7) { + LOGP(DSCH, LOGL_ERROR, "Incorrect TS index %u\n", tn); + return -EINVAL; + } + + /* Check whether required timeslot is allocated and configured */ + ts = trx->ts_list[tn]; + if (ts == NULL || ts->mf_layout == NULL) { + LOGP(DSCH, LOGL_ERROR, "Timeslot %u isn't configured\n", tn); + return -EINVAL; + } + + /** + * Change talloc context of primitive + * from trx to the parent ts + */ + talloc_steal(ts, prim); + + /* Add primitive to TS transmit queue */ + llist_add_tail(&prim->list, &ts->tx_prims); + + return 0; +} + enum gsm_phys_chan_config sched_trx_chan_nr2pchan_config(uint8_t chan_nr) { uint8_t cbits = chan_nr >> 3; diff --git a/src/host/trxcon/sched_trx.h b/src/host/trxcon/sched_trx.h index 1b74041..4209f53 100644 --- a/src/host/trxcon/sched_trx.h +++ b/src/host/trxcon/sched_trx.h @@ -235,6 +235,8 @@ struct llist_head list; /*! \brief Logical channel type */ enum trx_lchan_type chan; + /*! \brief Payload length */ + size_t payload_len; /*! \brief Payload */ uint8_t payload[0]; }; @@ -267,5 +269,11 @@ struct trx_lchan_state *sched_trx_find_lchan(struct trx_ts *ts, enum trx_lchan_type chan); +/* Primitive management functions */ +int sched_trx_init_prim(struct trx_instance *trx, struct trx_ts_prim **prim, + size_t pl_len, uint8_t chan_nr, uint8_t link_id); +int sched_trx_push_prim(struct trx_instance *trx, + struct trx_ts_prim *prim, uint8_t chan_nr); + int sched_trx_handle_rx_burst(struct trx_instance *trx, uint8_t tn, uint32_t burst_fn, sbit_t *bits, uint16_t nbits, int8_t rssi, float toa); -- To view, visit https://gerrit.osmocom.org/6774 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I8169a1ef4ef54d91b50f3e213e4842f54af8b499 Gerrit-PatchSet: 1 Gerrit-Project: osmocom-bb Gerrit-Branch: master Gerrit-Owner: Harald Welte <lafo...@gnumonks.org>