diff options
author | Vadim Yanitskiy <axilirator@gmail.com> | 2017-08-13 00:16:24 +0600 |
---|---|---|
committer | Vadim Yanitskiy <axilirator@gmail.com> | 2017-11-19 17:35:07 +0700 |
commit | 7d95f8821e82895f7952860923a7624287f9c42c (patch) | |
tree | 49ec058fd61bda0ddf4c0529e9071dd80e2d8515 /src | |
parent | 82b8c21b210535feaed98487f0df12f3acc2e46c (diff) |
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
Diffstat (limited to 'src')
-rw-r--r-- | src/host/trxcon/l1ctl.c | 57 | ||||
-rw-r--r-- | src/host/trxcon/sched_trx.c | 69 | ||||
-rw-r--r-- | src/host/trxcon/sched_trx.h | 8 |
3 files changed, 90 insertions, 44 deletions
diff --git a/src/host/trxcon/l1ctl.c b/src/host/trxcon/l1ctl.c index f193a7a5..f125948d 100644 --- a/src/host/trxcon/l1ctl.c +++ b/src/host/trxcon/l1ctl.c @@ -589,17 +589,13 @@ static int l1ctl_rx_dm_rel_req(struct l1ctl_link *l1l, struct msgb *msg) 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 @@ static int l1ctl_rx_data_req(struct l1ctl_link *l1l, struct msgb *msg) 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; - } - /* 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; + /* Push this primitive to transmit queue */ + rc = sched_trx_push_prim(l1l->trx, prim, chan_nr); + if (rc) { + talloc_free(prim); 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 956c261b..7f6729cb 100644 --- a/src/host/trxcon/sched_trx.c +++ b/src/host/trxcon/sched_trx.c @@ -417,6 +417,75 @@ void sched_trx_deactivate_all_lchans(struct trx_ts *ts) } } +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 1b74041c..4209f533 100644 --- a/src/host/trxcon/sched_trx.h +++ b/src/host/trxcon/sched_trx.h @@ -235,6 +235,8 @@ struct trx_ts_prim { 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 @@ int sched_trx_deactivate_lchan(struct trx_ts *ts, enum trx_lchan_type chan); 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); |