summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorVadim Yanitskiy <axilirator@gmail.com>2017-08-13 00:16:24 +0600
committerVadim Yanitskiy <axilirator@gmail.com>2017-11-19 17:35:07 +0700
commit7d95f8821e82895f7952860923a7624287f9c42c (patch)
tree49ec058fd61bda0ddf4c0529e9071dd80e2d8515 /src
parent82b8c21b210535feaed98487f0df12f3acc2e46c (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.c57
-rw-r--r--src/host/trxcon/sched_trx.c69
-rw-r--r--src/host/trxcon/sched_trx.h8
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);