summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas.Eversberg <jolly@eversberg.eu>2010-09-26 11:50:56 +0200
committerSylvain Munaut <tnt@246tNt.com>2010-09-28 08:04:18 +0200
commit732f102cc2ffd52f9013bc770fcaf36c3d04ddf5 (patch)
tree965312572c96db63b5c22d9a5bbe6a657a734d29
parent1b6c2593ebd3066f144a085dd0495c89928106a8 (diff)
fw/layer1: Add support for measurement messages from layer2/3
Written-by: Andreas.Eversberg <jolly@eversberg.eu> Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
-rw-r--r--src/target/firmware/include/layer1/async.h1
-rw-r--r--src/target/firmware/include/layer1/sync.h1
-rw-r--r--src/target/firmware/layer1/async.c13
-rw-r--r--src/target/firmware/layer1/l23_api.c16
-rw-r--r--src/target/firmware/layer1/sync.c1
5 files changed, 28 insertions, 4 deletions
diff --git a/src/target/firmware/include/layer1/async.h b/src/target/firmware/include/layer1/async.h
index ff23af5f..c6ca3204 100644
--- a/src/target/firmware/include/layer1/async.h
+++ b/src/target/firmware/include/layer1/async.h
@@ -24,6 +24,7 @@ static inline void l1a_unlock_sync(void)
/* safely enable a message into the L1S TX queue */
void l1a_txq_msgb_enq(struct llist_head *queue, struct msgb *msg);
+void l1a_meas_msgb_set(struct msgb *msg);
/* flush all pending msgb */
void l1a_txq_msgb_flush(struct llist_head *queue);
diff --git a/src/target/firmware/include/layer1/sync.h b/src/target/firmware/include/layer1/sync.h
index 4d99ba0f..f12f2dfb 100644
--- a/src/target/firmware/include/layer1/sync.h
+++ b/src/target/firmware/include/layer1/sync.h
@@ -77,6 +77,7 @@ struct l1s_state {
/* Transmit queues of pending packets for main DCCH and ACCH */
struct llist_head tx_queue[_NUM_L1S_CHAN];
+ struct msgb *tx_meas;
/* Which L1A completions are scheduled right now */
uint32_t scheduled_compl;
diff --git a/src/target/firmware/layer1/async.c b/src/target/firmware/layer1/async.c
index 0b11cccb..cf29e3bb 100644
--- a/src/target/firmware/layer1/async.c
+++ b/src/target/firmware/layer1/async.c
@@ -46,7 +46,18 @@ void l1a_txq_msgb_enq(struct llist_head *queue, struct msgb *msg)
local_irq_restore(flags);
}
-/* flush all pending msgb */
+void l1a_meas_msgb_set(struct msgb *msg)
+{
+ unsigned long flags;
+
+ local_firq_save(flags);
+ if (l1s.tx_meas)
+ msgb_free(l1s.tx_meas);
+ l1s.tx_meas = msg;
+ local_irq_restore(flags);
+}
+
+/* safely flush all pending msgb */
void l1a_txq_msgb_flush(struct llist_head *queue)
{
struct msgb *msg;
diff --git a/src/target/firmware/layer1/l23_api.c b/src/target/firmware/layer1/l23_api.c
index 2f1108f6..95704922 100644
--- a/src/target/firmware/layer1/l23_api.c
+++ b/src/target/firmware/layer1/l23_api.c
@@ -30,6 +30,7 @@
#include <byteorder.h>
#include <osmocore/msgb.h>
+#include <osmocore/protocol/gsm_04_08.h>
#include <comm/sercomm.h>
#include <layer1/sync.h>
@@ -246,6 +247,7 @@ static void l1ctl_rx_dm_rel_req(struct msgb *msg)
l1s.dedicated.type = GSM_DCHAN_NONE;
l1a_txq_msgb_flush(&l1s.tx_queue[L1S_CHAN_MAIN]);
l1a_txq_msgb_flush(&l1s.tx_queue[L1S_CHAN_SACCH]);
+ l1a_meas_msgb_set(NULL);
dsp_load_ciph_param(0, NULL);
}
@@ -286,9 +288,17 @@ static void l1ctl_rx_data_req(struct msgb *msg)
printd("L1CTL_DATA_REQ (link_id=0x%02x)\n", ul->link_id);
msg->l3h = data_ind->data;
- tx_queue = (ul->link_id & 0x40) ?
- &l1s.tx_queue[L1S_CHAN_SACCH] :
- &l1s.tx_queue[L1S_CHAN_MAIN];
+ if (ul->link_id & 0x40) {
+ struct gsm48_hdr *gh = (struct gsm48_hdr *)(data_ind->data + 5);
+ if (gh->proto_discr == GSM48_PDISC_RR
+ && gh->msg_type == GSM48_MT_RR_MEAS_REP) {
+ printd("updating measurement report\n");
+ l1a_meas_msgb_set(msg);
+ return;
+ }
+ tx_queue = &l1s.tx_queue[L1S_CHAN_SACCH];
+ } else
+ tx_queue = &l1s.tx_queue[L1S_CHAN_MAIN];
printd("ul=%p, ul->payload=%p, data_ind=%p, data_ind->data=%p l3h=%p\n",
ul, ul->payload, data_ind, data_ind->data, msg->l3h);
diff --git a/src/target/firmware/layer1/sync.c b/src/target/firmware/layer1/sync.c
index 1d2c0534..44958f74 100644
--- a/src/target/firmware/layer1/sync.c
+++ b/src/target/firmware/layer1/sync.c
@@ -381,6 +381,7 @@ void l1s_init(void)
for (i = 0; i < ARRAY_SIZE(l1s.tx_queue); i++)
INIT_LLIST_HEAD(&l1s.tx_queue[i]);
+ l1s.tx_meas = NULL;
sched_gsmtime_init();