FreeCalypso > hg > fc-magnetite
view src/g23m-gsm/dl/dl_dph.c @ 639:026c98f757a6
tpudrv12.h & targets/gtm900.h: our current support is for MGC2GSMT version only
As it turns out, there exist two different Huawei-made hw platforms both
bearing the marketing name GTM900-B: one is MG01GSMT, the other is MGC2GSMT.
The two are NOT fw-compatible: aside from flash chip differences which
should be handled by autodetection, the two hw platforms are already known
to have different RFFEs with different control signals, and there may be
other differences not yet known. Our current gtm900 build target is for
MGC2GSMT only; we do not yet have a specimen of MG01GSMT on hand, hence
no support for that version will be possible until and unless someone
provides one.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 30 Jan 2020 18:19:01 +0000 |
parents | 27a4235405c6 |
children |
line wrap: on
line source
/* +----------------------------------------------------------------------------- | Project : GSM-PS | Modul : DL_DPH +----------------------------------------------------------------------------- | Copyright 2002 Texas Instruments Berlin, AG | All rights reserved. | | This file is confidential and a trade secret of Texas | Instruments Berlin, AG | The receipt of or possession of this file does not convey | any rights to reproduce or disclose its contents or to | manufacture, use, or sell anything it may describe, in | whole, or in part, without the specific written consent of | Texas Instruments Berlin, AG. +----------------------------------------------------------------------------- | Purpose : This Modul defines the functions for distributing | all primitives of the lower layers. +----------------------------------------------------------------------------- */ #ifndef DL_DPH_C #define DL_DPH_C #define ENTITY_DL /*==== INCLUDES ===================================================*/ #include "typedefs.h" #include <string.h> #include "pconst.cdg" #include "vsi.h" #include "pconst.cdg" #include "custom.h" #include "gsm.h" #include "mon_dl.h" #include "prim.h" #include "pei.h" #include "tok.h" #include "ccdapi.h" #include "dl.h" #include "dl_trc.h" /*==== EXPORT =====================================================*/ /*==== PRIVAT =====================================================*/ #if defined(_SIMULATION_) && !defined(DL_2TO1) LOCAL void dph_ph_data_req (T_PH_DATA_REQ * data_req); #endif /* _SIMULATION_ && !DL_2TO1 */ #if defined(DL_2TO1) || defined(USE_L1M_GS001_1) LOCAL U8 convert_dcch_ch_type (U8 channel_type); #endif /* DL_2TO1 || USE_L1M_GS001_1 */ LOCAL void dl_process_downlink (UBYTE error_flag, UBYTE channel_type, UBYTE * frame, ULONG fn); /*==== VARIABLES ==================================================*/ /*==== FUNCTIONS ==================================================*/ #if defined(DL_2TO1) #if defined(_SIMULATION_) /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6147) MODULE : DL_DPH | | STATE : code ROUTINE : dph_ph_ready_to_send | +--------------------------------------------------------------------+ PURPOSE : Reception of a PH_READY_TO_SEND primitive. Uplink opportunity for simulation. */ GLOBAL void l1test_call_mphc_read_dcch (T_L1TEST_CALL_MPHC_READ_DCCH * ready) { UBYTE no_signalling_flag = NO_SIGNALLING; T_RADIO_FRAME *frame = NULL; GET_INSTANCE_DATA; dl_data->dl_active = FALSE; switch (ready->chn_mode) { case CM_SIGNALLING_ONLY: /* * Take over the behaviour of dll_read_dcch(): * No ch_type is given by the layer 1 for SDCCH and FACCH, * the first parameter ch_type of the fuction dl1_uplink_ind() get a * value set to zero. */ no_signalling_flag = SIG_ONLY; break; default: break; } frame = dl1_uplink_ind (0, no_signalling_flag); if (frame) { l1test_return_mphc_read_dcch (frame); } MY_PFREE (ready); } GLOBAL void l1test_call_mphc_read_sacch (T_L1TEST_CALL_MPHC_READ_SACCH * ready) { T_RADIO_FRAME *frame = NULL; GET_INSTANCE_DATA; dl_data->dl_active = FALSE; frame = dl1_uplink_ind (L2_CHANNEL_SACCH, SIG_ONLY); if (frame) { l1test_return_mphc_read_sacch (frame); } MY_PFREE (ready); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6147) MODULE : DL_DPH | | STATE : code ROUTINE : dph_ph_data_req | +--------------------------------------------------------------------+ PURPOSE : Sending of a PH_DATA_REQ primitive. Uplink for simulation. */ GLOBAL void l1test_return_mphc_read_dcch (T_RADIO_FRAME * frame) { PALLOC(data_req, L1TEST_RETURN_MPHC_READ_DCCH); TRACE_FUNCTION ("l1test_return_mphc_read_dcch()"); memcpy(data_req->l2_frame.frame_array, frame->frame_array, sizeof(data_req->l2_frame)); PSEND (hCommPL, data_req); } GLOBAL void l1test_return_mphc_read_sacch (T_RADIO_FRAME * frame) { PALLOC(data_req, L1TEST_RETURN_MPHC_READ_SACCH); TRACE_FUNCTION ("l1test_return_mphc_read_sacch()"); memcpy(data_req->l2_frame.frame_array, frame->frame_array, sizeof(data_req->l2_frame)); PSEND (hCommPL, data_req); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6147) MODULE : DL_DPH | | STATE : code ROUTINE : l1test_call_mphc_dcch_downlink | +--------------------------------------------------------------------+ PURPOSE : Reception of a L1TEST_CALL_MPHC_DCCH_DOWNLINK primitive. */ GLOBAL void l1test_call_mphc_dcch_downlink (T_L1TEST_CALL_MPHC_DCCH_DOWNLINK * data_ind) { /* * Take over the behaviour of dll_dcch_downlink(): * No ch_type is given by the layer 1 for SDCCH and FACCH, * the second parameter ch_type of the function dl_process_downlink() get a * value set to zero. */ dl_data->dl_active = FALSE; dl_process_downlink (data_ind->valid_flag, 0, data_ind->l2_frame.frame_array, NOT_PRESENT_32BIT); MY_PFREE (data_ind); } #endif /* _SIMULATION_ */ /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6147) MODULE : DL_DPH | | STATE : code ROUTINE : dph_ph_data_ind | +--------------------------------------------------------------------+ PURPOSE : Reception of a PH_DATA_IND primitive. This function is only available in stacks >= TCS5 (DL_2TO1). A function with the same name exist for the old GSM/GPRS stack. It is used for SACCH downlink on target as well as on simulation. In opposite to the old GSM/GPRS stack, a functional interface (l1test_call_mphc_dcch_downlink) is used by the dual mode stack implementation for SDCCH and FACCH during simulation. Therefore this function is only used for SACCH. */ GLOBAL void dph_ph_data_ind (T_MPHC_PH_DATA_IND * data_ind) { /* * Take over the behaviour of dll_dcch_downlink(): * No ch_type is given by the layer 1 for SDCCH and FACCH, * the second parameter ch_type of the function dl_process_downlink() get a * value set to zero. */ TRACE_FUNCTION ("dph_ph_data_ind() 2TO1"); if (data_ind->l2_channel_type EQ L2_CHANNEL_SACCH) dl_process_downlink (data_ind->error_cause, L2_CHANNEL_SACCH, data_ind->l2_frame.frame_array, NOT_PRESENT_32BIT); MY_PFREE (data_ind); } #else /* DL_2TO1 */ #if defined(_SIMULATION_) /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6147) MODULE : DL_DPH | | STATE : code ROUTINE : dph_ph_ready_to_send | +--------------------------------------------------------------------+ PURPOSE : Reception of a PH_READY_TO_SEND primitive. Uplink opportunity for simulation. */ GLOBAL void dph_ph_ready_to_send (T_PH_READY_TO_SEND * ready) { UBYTE no_signalling_flag = SIG_ONLY; T_RADIO_FRAME *frame; UBYTE ch_type; switch (ready->ch_type) { case L2_CHANNEL_FACCH_F: case L2_CHANNEL_FACCH_H: no_signalling_flag = NO_SIGNALLING; /*lint -fallthrough */ case L2_CHANNEL_SDCCH: /* * Take over the behaviour of dll_read_dcch(): * No ch_type is given by the layer 1 for SDCCH and FACCH, * the first parameter ch_type of the function dl1_uplink_ind() get a * value set to zero. */ ch_type = 0; break; default: ch_type = ready->ch_type; break; } frame = dl1_uplink_ind (ch_type, no_signalling_flag); if (frame) { PALLOC_SDU (data, PH_DATA_REQ, 23*BITS_PER_BYTE);/* T_PH_DATA_REQ */ /* * In case the value of ready->ch_type was set to zero above it has to set * to the value of dcch0_ch_type corresponding the behaviour of the * function dl1_uplink_ind(). if (ready->ch_type EQ 0) { T_DL_DATA *dl_data = dl_get_data (); ready->ch_type = dl_data->dcch0_ch_type ? dl_data->dcch0_ch_type : L2_CHANNEL_SDCCH; } */ memcpy (data->sdu.buf, frame, 23);/*lint !e419 (Warning -- Apparent data overrun) */ if (ready->ch_type EQ L2_CHANNEL_SACCH) { data->sdu.buf[0] = 0;/* layer 1 header occupies 2 bytes */ data->sdu.buf[1] = 0;/*lint !e415 (Warning -- access of out-of-bounds pointer) */ data->sdu.o_buf = 2 * BITS_PER_BYTE; data->sdu.l_buf = 21 * BITS_PER_BYTE; } else { data->sdu.o_buf = 0; data->sdu.l_buf = 23 * BITS_PER_BYTE; } data->ch_type = ready->ch_type; dph_ph_data_req (data); } MY_PFREE (ready); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6147) MODULE : DL_DPH | | STATE : code ROUTINE : dph_ph_data_req | +--------------------------------------------------------------------+ PURPOSE : Sending of a PH_DATA_REQ primitive. Uplink for simulation. */ LOCAL void dph_ph_data_req (T_PH_DATA_REQ * data_req) { TRACE_FUNCTION ("dph_ph_data_req()"); #if defined(DL_TRACE_WIN32) if (data_req->ch_type EQ L2_CHANNEL_SACCH) { /*lint -e416 (Warning -- creation of out-of-bounds pointer) */ FTRC (data_req->ch_type, data_req->sdu.buf+2, 1); /* uplink SACCH */ /*lint +e416 (Warning -- creation of out-of-bounds pointer) */ } else { FTRC (data_req->ch_type, data_req->sdu.buf, 1); /* uplink other */ } #endif /* DL_TRACE_WIN32 */ PSENDX (PL, data_req); } #endif /* _SIMULATION */ /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6147) MODULE : DL_DPH | | STATE : code ROUTINE : dph_ph_data_ind | +--------------------------------------------------------------------+ PURPOSE : Reception of a PH_DATA_IND primitive. This function is only available in the old GSM/GPRS stack (<= TCS4). A function with the same name exist for the dual mode stack. It can be used for SACCH downlink on target as well as on simulation. During simulation the old GSM/GPRS stack uses this primitive function for SDCCH and FACCH also. In this case it takes over the functional interface dll_dcch_downlink(). In the current implementation of the old GSM/GPRS stack the ALR queue is exclusively used for incoming PH_DATA_IND primitives from L1 for target builds. Only Acknowledged frames (SAPI=3) and frames with Bter format (short PD header) are forwarded to DL and handled by this function. */ GLOBAL void dph_ph_data_ind (T_PH_DATA_IND * ph_data_ind) { if (ph_data_ind) { #if defined(_SIMULATION_) /* * Take over the behaviour of dll_dcch_downlink(): * No ch_type is given by the layer 1 for SDCCH and FACCH, * the first parameter ch_type of the function dl_process_downlink() get a * value set to zero. */ switch (ph_data_ind->l2_channel_type) { case L2_CHANNEL_SDCCH: case L2_CHANNEL_FACCH_F: case L2_CHANNEL_FACCH_H: ph_data_ind->l2_channel_type = 0; break; default: break; } #else /* _SIMULATION */ if (ph_data_ind->l2_channel_type EQ L2_CHANNEL_SACCH) #endif /* _SIMULATION */ dl_process_downlink (ph_data_ind->error_cause, ph_data_ind->l2_channel_type, ph_data_ind->l2_frame.A, NOT_PRESENT_32BIT); MY_PFREE (ph_data_ind); } } #endif /* DL_2TO1 */ /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6147) MODULE : DL_DPH | | STATE : code ROUTINE : dl_process_downlink | +--------------------------------------------------------------------+ PURPOSE : really processing of layer 2 frame downlink. */ LOCAL void dl_process_downlink (UBYTE error_flag, UBYTE channel_type, UBYTE * frame, ULONG fn) { GET_INSTANCE_DATA; TRACE_FUNCTION ("dll_process_downlink()"); /* set the active dedicated channel type if necessary */ if (channel_type EQ 0) { TRACE_EVENT_WIN_P3 ("dl_process_downlink(%u,) -> ch=%u FN=%d", channel_type, dl_data->dcch0_ch_type, ((int)fn)); channel_type = dl_data->dcch0_ch_type ? dl_data->dcch0_ch_type : L2_CHANNEL_SDCCH; } else { TRACE_EVENT_WIN_P1 ("dl_process_downlink(%u,)", channel_type); } if (channel_type NEQ L2_CHANNEL_SACCH) dl_data->interrupt_context = TRUE; if (fn NEQ NOT_PRESENT_32BIT) dl_data->fn = fn; #if defined(DL_TRACE_ENABLED) { UCHAR trace_channel = TRACE_CH_UNKNOWN; UCHAR frame_sapi; switch (channel_type) { case L2_CHANNEL_SACCH: frame_sapi = ((*(frame + 2)) & 0x1c) >> 2; if (frame_sapi EQ PS_SAPI_0) trace_channel = C_DCCH0; else if (frame_sapi EQ PS_SAPI_3) trace_channel = C_DCCH3; break; case L2_CHANNEL_SDCCH: frame_sapi = ((*frame) & 0x1c) >> 2; if (frame_sapi EQ PS_SAPI_0) trace_channel = C_DCCH0; else if (frame_sapi EQ PS_SAPI_3) trace_channel = C_DCCH3; break; case L2_CHANNEL_FACCH_F: case L2_CHANNEL_FACCH_H: frame_sapi = ((*frame) & 0x1c) >> 2; if (frame_sapi EQ PS_SAPI_0) trace_channel = C_DCCH0; break; default: break; }/* endswitch chan */ if (error_flag EQ VALID_BLOCK) { DL_OFFLINE_TRACE (TRACE_DOWNLINK, trace_channel, channel_type, &frame[0]); } } #endif /* DL_TRACE_ENABLED */ #if defined(DL_TRACE_WIN32) if (error_flag EQ VALID_BLOCK) { if (channel_type EQ L2_CHANNEL_SACCH) FTRC (channel_type, frame+2, 0); /* downlink SACCH */ else FTRC (channel_type, frame, 0); /* downlink other */ } #endif /* DL_TRACE_WIN32 */ if (channel_type EQ 0) { DL_OFFLINE_TRACE (TRACE_DL_EVENT, TRACE_CH_UNKNOWN, channel_type, "DL:no valid channel type"); } else { dl_downlink (error_flag, channel_type, &frame[0], fn); } dl_data->interrupt_context = FALSE; } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6147) MODULE : DL_DPH | | STATE : code ROUTINE : dl1_uplink_ind | +--------------------------------------------------------------------+ PURPOSE : Functional Interface for the uplink direction of the logical channels SACCH/SDCCH/FACCH. (only used by the target) */ GLOBAL T_RADIO_FRAME * dl1_uplink_ind (UBYTE channel_type, UBYTE no_signalling_flag) { T_RADIO_FRAME * pRadioFrame; UCHAR channel; UCHAR sapi; UCHAR signalling = SIG_ONLY; GET_INSTANCE_DATA; dl_data->interrupt_context = TRUE; /* set the active dedicated channel type if necessary */ if (channel_type EQ 0) channel_type = dl_data->dcch0_ch_type; TRACE_EVENT_WIN_P1 ("dl1_uplink_ind(ch_type=%u,)", channel_type); switch (channel_type) { case L2_CHANNEL_SACCH: /* * The priority arrangement on the SACCH must ensure that if a SAPI = 3 * frame is awaiting transmission, two SAPI = 0 frames are not sent in * consecutive SACCH frames. In addition, for the mobile to network * direction it must also be ensured that any SAPI = 3 frame is followed * by at least one SAPI = 0 frame. * * SAPI = 3 is set as default value. The function dl_uplink() together with * the variable 'sacch_last_uplink_sapi' determind the actual value. * e.g. if last uplinked SACCH frame was one with SAPI=3 * or * if no SACCH SAPI=3 frame is awaiting transmission * then a SACCH SAPI=0 frame should be uplinked */ channel = C_SACCH0; sapi = PS_SAPI_3; TRACE_EVENT_WIN_P2 ("dl1_uplink_ind(%s, %s)", CH_TYPE_NAME[channel_type], signalling EQ SIG_ONLY?"SIG_ONLY":"NO_SIGNALLING"); break; default: TRACE_ERROR ("dl1_uplink_ind():no valid channel type, use SDCCH instead"); channel_type = L2_CHANNEL_SDCCH; /*lint -fallthrough*/ case L2_CHANNEL_FACCH_F: case L2_CHANNEL_FACCH_H: case L2_CHANNEL_SDCCH: /* * build frame for SAPI = 3 will be called (with lower priority) * if no data is waiting for SAPI = 0. */ channel = C_DCCH0; sapi = PS_SAPI_0; dl_data->cch[channel].ch_type = channel_type; signalling = no_signalling_flag; TRACE_EVENT_WIN_P3 ("dl1_uplink_ind(%s, %s) SAPI=%u", CH_TYPE_NAME[channel_type], signalling EQ SIG_ONLY?"SIG_ONLY":"NO_SIGNALLING", sapi); break; } pRadioFrame= dl_uplink (channel, sapi, signalling, FALSE); if (pRadioFrame) { #ifndef DL_2TO1 DL_OFFLINE_TRACE (TRACE_UPLINK, channel, channel_type, &pRadioFrame->A[0]); #else DL_OFFLINE_TRACE (TRACE_UPLINK, channel, channel_type, &pRadioFrame->frame_array[0]); #endif } dl_data->interrupt_context = FALSE; return pRadioFrame; /* return pointer to frame to layer 1 */ } #if defined(DL_2TO1) || defined(USE_L1M_GS001_1) /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6147) MODULE : DL_DPH | | STATE : code ROUTINE : convert_dcch_ch_type | +--------------------------------------------------------------------+ PURPOSE : Converts dedicated channel types to layer 2 channel types according to L1M_GS001_1 and L1M_GS001_3. */ LOCAL U8 convert_dcch_ch_type (U8 channel_type) { UBYTE ch_type; switch (channel_type) { case MPHC_CH_TCH_F: ch_type = L2_CHANNEL_FACCH_F;break; case MPHC_CH_TCH_H: ch_type = L2_CHANNEL_FACCH_H;break; case MPHC_CH_SDCCH_4: case MPHC_CH_SDCCH_8:ch_type = L2_CHANNEL_SDCCH;break; } return ch_type; } #endif /* DL_2TO1 || USE_L1M_GS001_1 */ /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6147) MODULE : DL_DPH | | STATE : code ROUTINE : dll_read_dcch | +--------------------------------------------------------------------+ PURPOSE : Functional Interface for the uplink direction of SDCCH/FACCH. Only used by the TI target, look into TI interface S922 or L1M_GS001_1. */ #if defined(DL_2TO1) || defined(USE_L1M_GS001_1) GLOBAL T_RADIO_FRAME * dll_read_dcch (U8 chn_mode, U8 channel_type) { return dl1_uplink_ind(convert_dcch_ch_type(channel_type), chn_mode); } #else /* DL_2TO1 || USE_L1M_GS001_1 */ GLOBAL T_RADIO_FRAME * dll_read_dcch (U8 chn_mode) { /* 0 stands for the currently active SDCCH and FACCH channel type */ return dl1_uplink_ind(0, chn_mode); } #endif /* DL_2TO1 || USE_L1M_GS001_1 */ /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6147) MODULE : DL_DPH | | STATE : code ROUTINE : dll_read_sacch | +--------------------------------------------------------------------+ PURPOSE : Functional Interface for the uplink direction of SACCH. Only used by the TI target, look into TI interface S922 or L1M_GS001_1. */ GLOBAL T_RADIO_FRAME * dll_read_sacch (UBYTE chn_mode) { return dl1_uplink_ind (L2_CHANNEL_SACCH, SIG_ONLY); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6147) MODULE : DL_DPH | | STATE : code ROUTINE : dll_dcch_downlink | +--------------------------------------------------------------------+ PURPOSE : Functional Interface for the downlink direction of FACCH/DCCH. Only used by the TI target, look into TI interface S922 or L1M_GS001_1. */ #if defined(DL_2TO1) || defined(USE_L1M_GS001_1) GLOBAL void dll_dcch_downlink(U32 * data_ptr, U8 valid_flag, U8 channel_type, U32 fn) { if ((data_ptr NEQ NULL) AND (valid_flag EQ DATA_VALID)) { dl_process_downlink (VALID_BLOCK, convert_dcch_ch_type(channel_type), (UBYTE *)data_ptr, fn); } } #else /* DL_2TO1 || USE_L1M_GS001_1 */ #if defined(SEND_FN_TO_L2_IN_DCCH) && (SEND_FN_TO_L2_IN_DCCH == 1) GLOBAL void dll_dcch_downlink(U32 * data_ptr, U8 valid_flag, U32 fn) { if ((data_ptr NEQ NULL) AND valid_flag) { /* * channel type 0 stands for currently active dedicated * SDCCH or FACCH channel type */ dl_process_downlink (VALID_BLOCK, 0, (UBYTE *)data_ptr, fn); } } #else /* SEND_FN_TO_L2_IN_DCCH == 1 */ GLOBAL void dll_dcch_downlink(U32 * data_ptr, U8 valid_flag) { if ((data_ptr NEQ NULL) AND valid_flag) { /* * channel type 0 stands for currently active dedicated * SDCCH or FACCH channel type */ dl_process_downlink (VALID_BLOCK, 0, (UBYTE *)data_ptr, NOT_PRESENT_32BIT); } } #endif /* SEND_FN_TO_L2_IN_DCCH == 1 */ #endif /* DL_2TO1 || USE_L1M_GS001_1 */ #endif /* DL_DPH_C */