firmware/layer1: introduce experimental PDCH support

Change-Id: I44531bbe8743c188cc5d4a6ca2a63000e41d6189
This commit is contained in:
Vadim Yanitskiy 2020-03-09 15:42:33 +07:00
parent d339623867
commit e5ee0e5ef1
6 changed files with 83 additions and 1 deletions

View File

@ -319,6 +319,12 @@ static int rx_ph_data_ind(struct osmocom_ms *ms, struct msgb *msg)
dl->snr, ccch->data, sizeof(ccch->data));
}
/* HACK: Do not pass PDTCH / PTCCH frames to LAPDm */
if (chan_type == RSL_CHAN_OSMO_PDCH) {
msgb_free(msg);
return 0;
}
/* determine LAPDm entity based on SACCH or not */
if (dl->link_id & 0x40)
le = &ms->lapdm_channel.lapdm_acch;

View File

@ -31,6 +31,9 @@ enum mframe_task {
MF_TASK_TCH_H_0,
MF_TASK_TCH_H_1,
MF_TASK_GPRS_PDTCH,
MF_TASK_GPRS_PTCCH,
MF_TASK_NEIGH_PM51_C0T0,
MF_TASK_NEIGH_PM51,
MF_TASK_NEIGH_PM26E,
@ -42,6 +45,7 @@ enum mframe_task {
enum mf_sched_item_flag {
MF_F_SACCH = (1 << 0),
MF_F_PTCCH = (1 << 1),
};
/* The scheduler itself */

View File

@ -124,6 +124,7 @@ struct l1s_state {
GSM_DCHAN_SDCCH_8_CBCH,
GSM_DCHAN_TCH_H,
GSM_DCHAN_TCH_F,
GSM_DCHAN_PDCH,
GSM_DCHAN_UNKNOWN,
} type;

View File

@ -78,6 +78,7 @@ static uint32_t chan_nr2mf_task_mask(uint8_t chan_nr, uint8_t neigh_mode)
uint8_t tn = chan_nr & 0x7;
uint8_t lch_idx;
enum mframe_task master_task = 0;
enum mframe_task add_task = 0;
uint32_t neigh_task = 0;
enum mf_type multiframe = 0;
@ -97,6 +98,12 @@ static uint32_t chan_nr2mf_task_mask(uint8_t chan_nr, uint8_t neigh_mode)
lch_idx = cbits & 0x7;
master_task = MF_TASK_SDCCH8_0 + lch_idx;
multiframe = MF51;
} else if ((cbits & 0x1f) == 0x18) {
/* Osmocom specific extension for PDTCH and PTCCH */
master_task = MF_TASK_GPRS_PDTCH;
add_task = MF_TASK_GPRS_PTCCH;
/* FIXME: is it really different from e.g. BCCH? */
multiframe = MFNONE;
} else if ((cbits & 0x1f) == 0x19) {
/* Osmocom specific extension for CBCH on SDCCH/4 */
master_task = MF_TASK_SDCCH4_CBCH;
@ -129,7 +136,7 @@ static uint32_t chan_nr2mf_task_mask(uint8_t chan_nr, uint8_t neigh_mode)
}
break;
}
return (1 << master_task) | neigh_task;
return (1 << master_task) | (1 << add_task) | neigh_task;
}
static int chan_nr2dchan_type(uint8_t chan_nr)
@ -144,6 +151,9 @@ static int chan_nr2dchan_type(uint8_t chan_nr)
return GSM_DCHAN_SDCCH_4;
} else if ((cbits & 0x18) == 0x08) {
return GSM_DCHAN_SDCCH_8;
} else if ((cbits & 0x1f) == 0x18) {
/* Osmocom-specific extension for PDCH */
return GSM_DCHAN_PDCH;
} else if ((cbits & 0x1f) == 0x19) {
/* Osmocom-specific extension for CBCH on SDCCH/4 */
return GSM_DCHAN_SDCCH_4_CBCH;

View File

@ -311,6 +311,58 @@ static const struct mframe_sched_item mf_neigh_pm26_odd[] = {
{ .sched_set = NULL }
};
/* See 3GPP TS 45.002, table 6 */
static const struct mframe_sched_item mf_gprs_pdtch[] = {
{ .sched_set = NB_QUAD_DL, .modulo = 13, .frame_nr = 0 },
{ .sched_set = NB_QUAD_DL, .modulo = 13, .frame_nr = 4 },
{ .sched_set = NB_QUAD_DL, .modulo = 13, .frame_nr = 8 },
#if 0
/* FIXME: we need to use different handler here to avoid
* sending dummy blocks and DCCH / SACCH data here. */
{ .sched_set = NB_QUAD_UL, .modulo = 13, .frame_nr = 0 },
{ .sched_set = NB_QUAD_UL, .modulo = 13, .frame_nr = 4 },
{ .sched_set = NB_QUAD_UL, .modulo = 13, .frame_nr = 8 },
#endif
{ .sched_set = NULL }
};
static const struct mframe_sched_item mf_gprs_ptcch[] = {
/* TODO: implement AB_PTCCH_UL for PTCCH/U */
/* TODO: implement NB_PTCCH_DL for PTCCH/D */
#if 0
/* PTCCH/D */
{ .sched_set = NB_PTCCH_DL, .modulo = 104, .frame_nr = 12, .flags = MF_F_PTCCH },
{ .sched_set = NB_PTCCH_DL, .modulo = 104, .frame_nr = 38, .flags = MF_F_PTCCH },
{ .sched_set = NB_PTCCH_DL, .modulo = 104, .frame_nr = 64, .flags = MF_F_PTCCH },
{ .sched_set = NB_PTCCH_DL, .modulo = 104, .frame_nr = 90, .flags = MF_F_PTCCH },
/* PTCCH/U for TAI 0 .. 3 */
{ .sched_set = AB_PTCCH_UL, .modulo = 416, .frame_nr = 12 },
{ .sched_set = AB_PTCCH_UL, .modulo = 416, .frame_nr = 38 },
{ .sched_set = AB_PTCCH_UL, .modulo = 416, .frame_nr = 64 },
{ .sched_set = AB_PTCCH_UL, .modulo = 416, .frame_nr = 90 },
/* PTCCH/U for TAI 4 .. 7 */
{ .sched_set = AB_PTCCH_UL, .modulo = 416, .frame_nr = 116 },
{ .sched_set = AB_PTCCH_UL, .modulo = 416, .frame_nr = 142 },
{ .sched_set = AB_PTCCH_UL, .modulo = 416, .frame_nr = 168 },
{ .sched_set = AB_PTCCH_UL, .modulo = 416, .frame_nr = 194 },
/* PTCCH/U for TAI 8 .. 11 */
{ .sched_set = AB_PTCCH_UL, .modulo = 416, .frame_nr = 220 },
{ .sched_set = AB_PTCCH_UL, .modulo = 416, .frame_nr = 246 },
{ .sched_set = AB_PTCCH_UL, .modulo = 416, .frame_nr = 272 },
{ .sched_set = AB_PTCCH_UL, .modulo = 416, .frame_nr = 298 },
/* PTCCH/U for TAI 12 .. 15 */
{ .sched_set = AB_PTCCH_UL, .modulo = 416, .frame_nr = 324 },
{ .sched_set = AB_PTCCH_UL, .modulo = 416, .frame_nr = 350 },
{ .sched_set = AB_PTCCH_UL, .modulo = 416, .frame_nr = 376 },
{ .sched_set = AB_PTCCH_UL, .modulo = 416, .frame_nr = 402 },
#endif
{ .sched_set = NULL }
};
/* Test TX */
static const struct mframe_sched_item mf_tx_all_nb[] = {
{ .sched_set = NB_QUAD_FH_UL, .modulo = 4, .frame_nr = 0 },
@ -345,6 +397,9 @@ static const struct mframe_sched_item *sched_set_for_task[32] = {
[MF_TASK_TCH_H_0] = mf_tch_h_0,
[MF_TASK_TCH_H_1] = mf_tch_h_1,
[MF_TASK_GPRS_PDTCH] = mf_gprs_pdtch,
[MF_TASK_GPRS_PTCCH] = mf_gprs_ptcch,
[MF_TASK_NEIGH_PM51_C0T0] = mf_neigh_pm51_c0t0,
[MF_TASK_NEIGH_PM51] = mf_neigh_pm51,
[MF_TASK_NEIGH_PM26E] = mf_neigh_pm26_even,
@ -415,6 +470,10 @@ uint8_t mframe_task2chan_nr(enum mframe_task mft, uint8_t ts)
break;
/* Osmocom specific extensions */
case MF_TASK_GPRS_PDTCH:
case MF_TASK_GPRS_PTCCH:
cbits = 0x18;
break;
case MF_TASK_SDCCH4_CBCH:
cbits = 0x19;
break;

View File

@ -126,6 +126,8 @@ static int l1s_nb_resp(__unused uint8_t p1, uint8_t burst_id, uint16_t p3)
/* Set SACCH indication in Link IDentifier */
if (mf_task_flags & MF_F_SACCH)
rxnb.dl->link_id = 0x40;
if (mf_task_flags & MF_F_PTCCH)
rxnb.dl->link_id = 0x80;
else
rxnb.dl->link_id = 0x00;