diff options
author | Sylvain Munaut <tnt@246tNt.com> | 2010-06-20 22:40:03 +0200 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2010-06-22 06:37:09 +0200 |
commit | 38c6b4b35a4400a62b0e534c9326154bb4f232f9 (patch) | |
tree | 56d898f68fced20858b998571c8885e7b23a8831 | |
parent | a3e0c559a45f3c719082acf9eb2f7657ea4e35b5 (diff) |
fw/layer1: Add support CCCH combined/non-combined
We introduce the concept of CCCH mode. It can be either
- NONE: receive BCCCH only
- COMBINED: CCCH on a BCCH/CCCH+SDDCH/4
- NON_COMBINED: CCCH on a BCCH/CCCH
There is also a new command to change the mode without having
to do the resync.
Currently, we keep the previous default behavior of requesting
a combined CCCH by default
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
-rw-r--r-- | include/l1a_l23_interface.h | 25 | ||||
-rw-r--r-- | src/host/layer23/include/osmocom/l1ctl.h | 5 | ||||
-rw-r--r-- | src/host/layer23/src/app_phone.c | 4 | ||||
-rw-r--r-- | src/host/layer23/src/bcch_scan.c | 3 | ||||
-rw-r--r-- | src/host/layer23/src/gsm322.c | 3 | ||||
-rw-r--r-- | src/host/layer23/src/l1ctl.c | 20 | ||||
-rw-r--r-- | src/target/firmware/include/layer1/sync.h | 2 | ||||
-rw-r--r-- | src/target/firmware/layer1/l23_api.c | 41 | ||||
-rw-r--r-- | src/target/firmware/layer1/prim_fbsb.c | 5 |
9 files changed, 101 insertions, 7 deletions
diff --git a/include/l1a_l23_interface.h b/include/l1a_l23_interface.h index 95ec82b2..741221bc 100644 --- a/include/l1a_l23_interface.h +++ b/include/l1a_l23_interface.h @@ -39,6 +39,14 @@ #define L1CTL_RESET_REQ 14 #define L1CTL_RESET_CONF 15 #define L1CTL_DATA_CONF 16 +#define L1CTL_CCCH_MODE_REQ 17 +#define L1CTL_CCCH_MODE_CONF 18 + +enum ccch_mode { + CCCH_MODE_NONE = 0, + CCCH_MODE_NON_COMBINED, + CCCH_MODE_COMBINED, +}; /* * NOTE: struct size. We do add manual padding out of the believe @@ -84,6 +92,12 @@ struct l1ctl_fbsb_conf { /* FIXME: contents of cell_info ? */ } __attribute__((packed)); +/* CCCH mode was changed */ +struct l1ctl_ccch_mode_conf { + uint8_t ccch_mode; /* enum ccch_mode */ + uint8_t padding[3]; +} __attribute__((packed)); + /* data on the CCCH was found. This is following the header */ struct l1ctl_data_ind { uint8_t data[23]; @@ -117,7 +131,7 @@ struct l1ctl_fbsb_req { uint8_t num_freqerr_avg; uint8_t flags; /* L1CTL_FBSB_F_* */ uint8_t sync_info_idx; - uint8_t reserved; + uint8_t ccch_mode; /* enum ccch_mode */ } __attribute__((packed)); #define L1CTL_FBSB_F_FB0 (1 << 0) @@ -125,6 +139,15 @@ struct l1ctl_fbsb_req { #define L1CTL_FBSB_F_SB (1 << 2) #define L1CTL_FBSB_F_FB01SB (L1CTL_FBSB_F_FB0|L1CTL_FBSB_F_FB1|L1CTL_FBSB_F_SB) +/* + * msg for CCCH_MODE_REQ + * the l1_info_ul header is in front + */ +struct l1ctl_ccch_mode_req { + uint8_t ccch_mode; /* enum ccch_mode */ + uint8_t padding[3]; +} __attribute__((packed)); + /* the l1_info_ul header is in front */ struct l1ctl_rach_req { uint8_t ra; diff --git a/src/host/layer23/include/osmocom/l1ctl.h b/src/host/layer23/include/osmocom/l1ctl.h index 48aeaadd..2bcbdb32 100644 --- a/src/host/layer23/include/osmocom/l1ctl.h +++ b/src/host/layer23/include/osmocom/l1ctl.h @@ -20,7 +20,10 @@ int tx_ph_rach_req(struct osmocom_ms *ms); int tx_ph_dm_est_req(struct osmocom_ms *ms, uint16_t band_arfcn, uint8_t chan_nr); /* Transmit FBSB_REQ */ int l1ctl_tx_fbsb_req(struct osmocom_ms *ms, uint16_t arfcn, - uint8_t flags, uint16_t timeout, uint8_t sync_info_idx); + uint8_t flags, uint16_t timeout, uint8_t sync_info_idx, + uint8_t ccch_mode); + +int l1ctl_tx_ccch_mode_req(struct osmocom_ms *ms, uint8_t ccch_mode); int l1ctl_tx_echo_req(struct osmocom_ms *ms, unsigned int len); diff --git a/src/host/layer23/src/app_phone.c b/src/host/layer23/src/app_phone.c index 17083d78..7258f569 100644 --- a/src/host/layer23/src/app_phone.c +++ b/src/host/layer23/src/app_phone.c @@ -44,7 +44,9 @@ static int signal_cb(unsigned int subsys, unsigned int signal, switch (signal) { case S_L1CTL_RESET: ms = signal_data; - return l1ctl_tx_fbsb_req(ms, ms->test_arfcn, L1CTL_FBSB_F_FB01SB, 100, 0); + return l1ctl_tx_fbsb_req(ms, ms->test_arfcn, + L1CTL_FBSB_F_FB01SB, 100, 0, + CCCH_MODE_COMBINED); break; } return 0; diff --git a/src/host/layer23/src/bcch_scan.c b/src/host/layer23/src/bcch_scan.c index a8bd11cf..c542129a 100644 --- a/src/host/layer23/src/bcch_scan.c +++ b/src/host/layer23/src/bcch_scan.c @@ -154,7 +154,8 @@ static int _cinfo_start_arfcn(unsigned int band_arfcn) /* ask L1 to try to tune to new ARFCN */ /* FIXME: decode band */ - rc = l1ctl_tx_fbsb_req(fps.ms, band_arfcn, L1CTL_FBSB_F_FB01SB, 100, 0); + rc = l1ctl_tx_fbsb_req(fps.ms, band_arfcn, + L1CTL_FBSB_F_FB01SB, 100, 0, CCCH_MODE_COMBINED); if (rc < 0) return rc; diff --git a/src/host/layer23/src/gsm322.c b/src/host/layer23/src/gsm322.c index 8536a103..9ffc7693 100644 --- a/src/host/layer23/src/gsm322.c +++ b/src/host/layer23/src/gsm322.c @@ -222,7 +222,8 @@ int gsm322_cs_sendmsg(struct osmocom_ms *ms, struct msgb *msg) static int gsm322_sync_to_cell(struct osmocom_ms *ms, struct gsm322_cellsel *cs) { return l1ctl_tx_fbsb_req(ms, cs->arfcn, - L1CTL_FBSB_F_FB01SB, 100, 0); + L1CTL_FBSB_F_FB01SB, 100, 0, + CCCH_MODE_COMBINED); } static void gsm322_unselect_cell(struct gsm322_cellsel *cs) diff --git a/src/host/layer23/src/l1ctl.c b/src/host/layer23/src/l1ctl.c index 63628b0f..1239b99c 100644 --- a/src/host/layer23/src/l1ctl.c +++ b/src/host/layer23/src/l1ctl.c @@ -233,7 +233,8 @@ int tx_ph_data_req(struct osmocom_ms *ms, struct msgb *msg, /* Transmit FBSB_REQ */ int l1ctl_tx_fbsb_req(struct osmocom_ms *ms, uint16_t arfcn, - uint8_t flags, uint16_t timeout, uint8_t sync_info_idx) + uint8_t flags, uint16_t timeout, uint8_t sync_info_idx, + uint8_t ccch_mode) { struct msgb *msg; struct l1ctl_fbsb_req *req; @@ -253,6 +254,23 @@ int l1ctl_tx_fbsb_req(struct osmocom_ms *ms, uint16_t arfcn, req->num_freqerr_avg = 3; req->flags = flags; req->sync_info_idx = sync_info_idx; + req->ccch_mode = ccch_mode; + + return osmo_send_l1(ms, msg); +} + +/* Transmit L1CTL_CCCH_MODE_REQ */ +int l1ctl_tx_ccch_mode_req(struct osmocom_ms *ms, uint8_t ccch_mode) +{ + struct msgb *msg; + struct l1ctl_ccch_mode_req *req; + + msg = osmo_l1_alloc(L1CTL_CCCH_MODE_REQ); + if (!msg) + return -1; + + req = (struct l1ctl_ccch_mode_req *) msgb_put(msg, sizeof(*req)); + req->ccch_mode = ccch_mode; return osmo_send_l1(ms, msg); } diff --git a/src/target/firmware/include/layer1/sync.h b/src/target/firmware/include/layer1/sync.h index 171fb3bb..137ea9f8 100644 --- a/src/target/firmware/include/layer1/sync.h +++ b/src/target/firmware/include/layer1/sync.h @@ -13,6 +13,8 @@ struct l1_cell_info { uint16_t arfcn; /* what's the BSIC of the cell (from SCH burst decoding) */ uint8_t bsic; + /* Combined or non-combined CCCH */ + uint8_t ccch_mode; /* enum ccch_mode */ /* whats the delta of the cells current GSM frame number * compared to our current local frame number */ int32_t fn_offset; diff --git a/src/target/firmware/layer1/l23_api.c b/src/target/firmware/layer1/l23_api.c index 72995c2e..90aef764 100644 --- a/src/target/firmware/layer1/l23_api.c +++ b/src/target/firmware/layer1/l23_api.c @@ -170,6 +170,41 @@ static void l1ctl_rx_reset_req(struct msgb *msg) } } +/* Transmit a L1CTL_CCCH_MODE_CONF */ +static void l1ctl_tx_ccch_mode_conf(uint8_t ccch_mode) +{ + struct msgb *msg = l1ctl_msgb_alloc(L1CTL_CCCH_MODE_CONF); + struct l1ctl_ccch_mode_conf *mode_conf; + mode_conf = (struct l1ctl_ccch_mode_conf *) + msgb_put(msg, sizeof(*mode_conf)); + mode_conf->ccch_mode = ccch_mode; + + l1_queue_for_l2(msg); +} + +/* receive a L1CTL_CCCH_MODE_REQ from L23 */ +static void l1ctl_rx_ccch_mode_req(struct msgb *msg) +{ + struct l1ctl_hdr *l1h = (struct l1ctl_hdr *) msg->data; + struct l1ctl_ccch_mode_req *ccch_mode_req = + (struct l1ctl_ccch_mode_req *) l1h->data; + uint8_t ccch_mode = ccch_mode_req->ccch_mode; + + /* pre-set the CCCH mode */ + l1s.serving_cell.ccch_mode = ccch_mode; + + /* Update task */ + mframe_disable(MF_TASK_CCCH_COMB); + mframe_disable(MF_TASK_CCCH); + + if (ccch_mode == CCCH_MODE_COMBINED) + mframe_enable(MF_TASK_CCCH_COMB); + else if (ccch_mode == CCCH_MODE_NON_COMBINED) + mframe_enable(MF_TASK_CCCH); + + l1ctl_tx_ccch_mode_conf(ccch_mode); +} + /* callback from SERCOMM when L2 sends a message to L1 */ static void l1a_l23_rx_cb(uint8_t dlci, struct msgb *msg) { @@ -214,6 +249,9 @@ static void l1a_l23_rx_cb(uint8_t dlci, struct msgb *msg) trf6151_rx_window(0, ntohs(sync_req->band_arfcn), 40, 0); tpu_end_scenario(); + /* pre-set the CCCH mode */ + l1s.serving_cell.ccch_mode = sync_req->ccch_mode; + printd("Starting FCCH Recognition\n"); l1s_fbsb_req(1, sync_req); break; @@ -263,6 +301,9 @@ static void l1a_l23_rx_cb(uint8_t dlci, struct msgb *msg) case L1CTL_RESET_REQ: l1ctl_rx_reset_req(msg); break; + case L1CTL_CCCH_MODE_REQ: + l1ctl_rx_ccch_mode_req(msg); + break; } exit_msgbfree: diff --git a/src/target/firmware/layer1/prim_fbsb.c b/src/target/firmware/layer1/prim_fbsb.c index 0333017f..fe87996c 100644 --- a/src/target/firmware/layer1/prim_fbsb.c +++ b/src/target/firmware/layer1/prim_fbsb.c @@ -257,7 +257,10 @@ static int l1s_sbdet_resp(__unused uint8_t p1, uint8_t attempt, l1s_reset_hw(); /* enable the MF Task for BCCH reading */ mframe_enable(MF_TASK_BCCH_NORM); - mframe_enable(MF_TASK_CCCH_COMB); + if (l1s.serving_cell.ccch_mode == CCCH_MODE_COMBINED) + mframe_enable(MF_TASK_CCCH_COMB); + else if (l1s.serving_cell.ccch_mode == CCCH_MODE_NON_COMBINED) + mframe_enable(MF_TASK_CCCH); l1s_compl_sched(L1_COMPL_FB); |