summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSylvain Munaut <tnt@246tNt.com>2010-09-26 23:03:18 +0200
committerSylvain Munaut <tnt@246tNt.com>2010-09-28 08:04:19 +0200
commit61fdec01f57704064b31b336687110ec4caf11e3 (patch)
tree61524974f255a63dc00c285f0251851c47c1a6cb
parent9257fe53bfe4387cdd7a78f1fbd1c93134f5ab0b (diff)
fw/layer1: Process the tch_mode and store it for later use
Currently unused since no TCH support ... Will be used by future commits. Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
-rw-r--r--src/target/firmware/include/layer1/async.h3
-rw-r--r--src/target/firmware/include/layer1/sync.h3
-rw-r--r--src/target/firmware/layer1/async.c20
-rw-r--r--src/target/firmware/layer1/l23_api.c33
4 files changed, 59 insertions, 0 deletions
diff --git a/src/target/firmware/include/layer1/async.h b/src/target/firmware/include/layer1/async.h
index c6ca3204..f4d0b5a9 100644
--- a/src/target/firmware/include/layer1/async.h
+++ b/src/target/firmware/include/layer1/async.h
@@ -41,6 +41,9 @@ void l1a_mftask_enable(enum mframe_task task);
/* Disable a repeating multiframe task */
void l1a_mftask_disable(enum mframe_task task);
+/* Set TCH mode */
+uint8_t l1a_tch_mode_set(uint8_t mode);
+
/* Execute pending L1A completions */
void l1a_compl_execute(void);
diff --git a/src/target/firmware/include/layer1/sync.h b/src/target/firmware/include/layer1/sync.h
index f12f2dfb..e55fddcd 100644
--- a/src/target/firmware/include/layer1/sync.h
+++ b/src/target/firmware/include/layer1/sync.h
@@ -75,6 +75,9 @@ struct l1s_state {
int8_t ta;
uint8_t tx_power;
+ /* TCH mode */
+ uint8_t tch_mode;
+
/* Transmit queues of pending packets for main DCCH and ACCH */
struct llist_head tx_queue[_NUM_L1S_CHAN];
struct msgb *tx_meas;
diff --git a/src/target/firmware/layer1/async.c b/src/target/firmware/layer1/async.c
index cf29e3bb..69301298 100644
--- a/src/target/firmware/layer1/async.c
+++ b/src/target/firmware/layer1/async.c
@@ -27,12 +27,14 @@
#include <asm/system.h>
#include <osmocore/msgb.h>
+#include <osmocore/protocol/gsm_04_08.h>
#include <layer1/sync.h>
#include <layer1/async.h>
#include <layer1/mframe_sched.h>
#include <layer1/sched_gsmtime.h>
#include <layer1/l23_api.h>
+#include <calypso/l1_environment.h>
extern const struct tdma_sched_item rach_sched_set_ul[];
@@ -90,6 +92,24 @@ void l1a_mftask_set(uint32_t tasks)
mframe_set(tasks);
}
+/* Set TCH mode */
+uint8_t l1a_tch_mode_set(uint8_t mode)
+{
+ switch (mode) {
+ case GSM48_CMODE_SPEECH_V1:
+ l1s.tch_mode = TCH_FS_MODE;
+ break;
+ case GSM48_CMODE_SPEECH_EFR:
+ l1s.tch_mode = TCH_EFR_MODE;
+ break;
+ default:
+ mode = GSM48_CMODE_SIGN;
+ l1s.tch_mode = SIG_ONLY_MODE;
+ }
+
+ return mode;
+}
+
/* Initialize asynchronous part of Layer1 */
void l1a_init(void)
{
diff --git a/src/target/firmware/layer1/l23_api.c b/src/target/firmware/layer1/l23_api.c
index 95704922..0aa5b1a2 100644
--- a/src/target/firmware/layer1/l23_api.c
+++ b/src/target/firmware/layer1/l23_api.c
@@ -185,6 +185,9 @@ static void l1ctl_rx_dm_est_req(struct msgb *msg)
l1s.dedicated.h0.arfcn = ntohs(est_req->h0.band_arfcn);
}
+ /* TCH mode */
+ l1a_tch_mode_set(est_req->tch_mode);
+
/* figure out which MF tasks to enable */
l1a_mftask_set(1 << chan_nr2mf_task(ul->chan_nr));
}
@@ -249,6 +252,7 @@ static void l1ctl_rx_dm_rel_req(struct msgb *msg)
l1a_txq_msgb_flush(&l1s.tx_queue[L1S_CHAN_SACCH]);
l1a_meas_msgb_set(NULL);
dsp_load_ciph_param(0, NULL);
+ l1a_tch_mode_set(GSM48_CMODE_SIGN);
}
/* receive a L1CTL_PARAM_REQ from L23 */
@@ -401,6 +405,32 @@ static void l1ctl_rx_ccch_mode_req(struct msgb *msg)
l1ctl_tx_ccch_mode_conf(ccch_mode);
}
+/* Transmit a L1CTL_TCH_MODE_CONF */
+static void l1ctl_tx_tch_mode_conf(uint8_t tch_mode)
+{
+ struct msgb *msg = l1ctl_msgb_alloc(L1CTL_TCH_MODE_CONF);
+ struct l1ctl_tch_mode_conf *mode_conf;
+ mode_conf = (struct l1ctl_tch_mode_conf *)
+ msgb_put(msg, sizeof(*mode_conf));
+ mode_conf->tch_mode = tch_mode;
+
+ l1_queue_for_l2(msg);
+}
+
+/* receive a L1CTL_TCH_MODE_REQ from L23 */
+static void l1ctl_rx_tch_mode_req(struct msgb *msg)
+{
+ struct l1ctl_hdr *l1h = (struct l1ctl_hdr *) msg->data;
+ struct l1ctl_tch_mode_req *tch_mode_req =
+ (struct l1ctl_tch_mode_req *) l1h->data;
+ uint8_t tch_mode = tch_mode_req->tch_mode;
+
+ printd("L1CTL_TCH_MODE_REQ (mode=0x%02x)\n", tch_mode);
+ tch_mode = l1a_tch_mode_set(tch_mode);
+
+ l1ctl_tx_tch_mode_conf(tch_mode);
+}
+
/* callback from SERCOMM when L2 sends a message to L1 */
static void l1a_l23_rx_cb(uint8_t dlci, struct msgb *msg)
{
@@ -458,6 +488,9 @@ static void l1a_l23_rx_cb(uint8_t dlci, struct msgb *msg)
case L1CTL_CCCH_MODE_REQ:
l1ctl_rx_ccch_mode_req(msg);
break;
+ case L1CTL_TCH_MODE_REQ:
+ l1ctl_rx_tch_mode_req(msg);
+ break;
}
exit_msgbfree: