FreeCalypso > hg > fc-tourmaline
view src/g23m-gprs/cci/cci_fbsf.c @ 275:79cfefc1e2b4
audio mode load: gracefully handle mode files of wrong AEC version
Unfortunately our change of enabling L1_NEW_AEC (which is necessary
in order to bring our Calypso ARM fw into match with the underlying
DSP reality) brings along a change in the audio mode file binary
format and file size - all those new tunable AEC parameters do need
to be stored somewhere, after all. But we already have existing
mode files in the old format, and setting AEC config to garbage when
loading old audio modes (which is what would happen without the
present change) is not an appealing proposition.
The solution implemented in the present change is as follows: the
audio mode loading code checks the file size, and if it differs
from the active version of T_AUDIO_MODE, the T_AUDIO_AEC_CFG structure
is cleared - set to the default (disabled AEC) for the compiled type
of AEC. We got lucky in that this varying T_AUDIO_AEC_CFG structure
sits at the end of T_AUDIO_MODE!
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 30 Jul 2021 02:55:48 +0000 |
parents | fa8dc04885d8 |
children |
line wrap: on
line source
/* +----------------------------------------------------------------------------- | Project : | Modul : cci_fbsf.c +----------------------------------------------------------------------------- | 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 module implements local functions for service FBS of | entity CCI. +----------------------------------------------------------------------------- */ #define CCI_FBSF_C #define ENTITY_LLC /*==== INCLUDES =============================================================*/ #include <string.h> #include "typedefs.h" /* to get Condat data types */ #include "vsi.h" /* to get a lot of macros */ #include "macdef.h" #include "gprs.h" #include "gsm.h" /* to get a lot of macros */ #include "cnf_llc.h" /* to get cnf-definitions */ #include "mon_llc.h" /* to get mon-definitions */ #include "prim.h" /* to get the definitions of used SAP and directions */ #include "cci.h" /* to get the global entity definitions */ #include "llc.h" /* to get the global entity definitions */ #include "cci_fbsf.h" #include "llc_txp.h" #include "llc_rxp.h" #ifndef TI_PS_OP_CIPH_DRIVER #ifdef _GEA_SIMULATION_ #include "cci_hw_sim.h" #endif #if !defined(_GEA_SIMULATION_) && !defined(LL_2to1) #include "config/chipset.cfg" #if (CHIPSET == 12) || (CHIPSET == 14) #include "cci_gea_start.h" #endif /* CHIPSET */ #endif /* ! _GEA_SIMULATION_ && !LL_2to1 */ /* local buffer for the copy of ciphering key */ static USHORT tmp_key[4]; /*==== CONST ================================================================*/ /*==== LOCAL VARS ===========================================================*/ #ifdef _GEA_SIMULATION_ USHORT* hw_reg = NULL; #endif /*==== LOCAL FUNCTION ===========================================================*/ LOCAL void ciph_get_result (T_CIPH_out_data *out_data, U8 *status); LOCAL void ciph_init (void); LOCAL void ciph_reset_hw (void); LOCAL UBYTE ciph_fcs_check (UBYTE *fcs_start); LOCAL void ciph_get_ciphered_data (T_CIPH_out_data *out_data); LOCAL void ciph_get_deciphered_data (T_CIPH_out_data *out_data, U8 *status); LOCAL void ciph_fill_ul_reg (T_CIPH_cipher_req_parms *cipher_req_parms, T_CIPH_in_data_list *in_data_list); LOCAL void ciph_fill_dl_reg (T_CIPH_cipher_req_parms *cipher_req_parms, T_CIPH_in_data_list *in_data_list); /*==== PRIVATE FUNCTIONS ====================================================*/ #ifdef LLC_TRACE_GEA_PARAM LOCAL void cci_trace_gea_param( void ); #endif /*==== PUBLIC FUNCTIONS =====================================================*/ /* +------------------------------------------------------------------------------ | Function : ciph_cipher_req_sim +------------------------------------------------------------------------------ | Description : Handles the primitive ciph_cipher_req. It is used to request | ciphering or deciphering of a LLC PDU. | | Parameters : | +------------------------------------------------------------------------------ */ GLOBAL void ciph_cipher_req_sim (T_CIPH_cipher_req_parms *cipher_req_parms_ptr, T_CIPH_in_data_list *in_data_ptr, T_CIPH_out_data *out_data_ptr, U8 *status) { USHORT volatile *cntl = cci_data->fbs.cntl_reg; int i = 0; ULONG cnt = 0; TRACE_FUNCTION( "ciph_cipher_req" ); /* reset GEA (enables and then disables clock) */ ciph_reset_hw(); *cntl |= CL_ENABLE; /* fill UL or DL configuration and data registers */ if (cci_data->fbs.ciph_params.direction == CIPH_UPLINK_DIR) { ciph_fill_ul_reg (cipher_req_parms_ptr, in_data_ptr ); #ifdef LL_2to1 *cntl = (*cntl & UL_DL_UP) | START; #else /* LL_2to1 */ #if (CHIPSET == 12) || (CHIPSET == 14) /* GEA work-around */ *cntl = (*cntl & UL_DL_UP); gea_start(); #else *cntl = (*cntl & UL_DL_UP) | START; #endif #endif /* LL_2to1 */ } else { ciph_fill_dl_reg (cipher_req_parms_ptr, in_data_ptr ); #ifdef LL_2to1 *cntl |= (UL_DL_DOWN | START); #else /* LL_2to1 */ #if (CHIPSET == 12) || (CHIPSET == 14) /* GEA work-around */ *cntl |= (UL_DL_DOWN); gea_start(); #else *cntl |= (UL_DL_DOWN | START); #endif #endif /* LL_2to1 */ } out_data_ptr->len = 0; for (i = 0; i < in_data_ptr->c_in_data; i++) { out_data_ptr->len += in_data_ptr->ptr_in_data[i].len; } if (cci_data->fbs.ciph_params.direction == CIPH_DOWNLINK_DIR) { out_data_ptr->len -= FCS_SIZE; } else { out_data_ptr->len += FCS_SIZE; } #ifdef _GEA_SIMULATION_ if (cci_data->fbs.ciph_params.direction == CIPH_UPLINK_DIR) { ciph_hw_sim_cipher(out_data_ptr->len); } else { ciph_hw_sim_decipher(); } #endif /* poll until data is processed */ if(cci_data->fbs.cci_info_trace){ while (*(cci_data->fbs.status_reg) & CHECK_WORKING){ cnt += 1; }; TRACE_EVENT_P1("INFO CCI: ciphering completed, counter: %d", cnt); } else { while (*(cci_data->fbs.status_reg) & CHECK_WORKING){ }; } /* verify ciphering key, whether it has been corrupted */ if(cci_data->fbs.cci_info_trace){ if(*cci_data->fbs.kc_reg1 != tmp_key[0] || *cci_data->fbs.kc_reg2 != tmp_key[1] || *cci_data->fbs.kc_reg3 != tmp_key[2] || *cci_data->fbs.kc_reg4 != tmp_key[3]) { TRACE_ERROR("CCI ERROR: Ciphering key has been corrupted!!"); TRACE_EVENT_P4("CCI: original key: %04x %04x %04x %04x %04x %04x", tmp_key[0], tmp_key[1], tmp_key[2], tmp_key[3]); TRACE_EVENT_P4("CCI: kc key: %04x %04x %04x %04x %04x %04x", *cci_data->fbs.kc_reg1, *cci_data->fbs.kc_reg2, *cci_data->fbs.kc_reg3, *cci_data->fbs.kc_reg4); } } /* and finally handle the result */ ciph_get_result(out_data_ptr, status); /* disable clock until new frames are to process */ *cntl &= CL_DISABLE; } /* +------------------------------------------------------------------------------ | Function : ciph_init_cipher_req_sim +------------------------------------------------------------------------------ | Description : Handles the primitive ciph_init_cipher_req_sim. | | Parameters : | +------------------------------------------------------------------------------ */ GLOBAL void ciph_init_cipher_req_sim (T_CIPH_init_cipher_req_parms *init_cipher_req_parms_ptr, void (*read_data) (void)) { if (!cci_data->fbs.initialized){ ciph_init(); cci_data->fbs.initialized = TRUE; } cci_data->fbs.ciph_params = *init_cipher_req_parms_ptr; } /* +------------------------------------------------------------------------------ | Function : ciph_get_result +------------------------------------------------------------------------------ | Description : Handles the function ciph_get_result. This function gets the | ciphered data in uplink direction or deciphered data in | downlink direction | | Parameters : +------------------------------------------------------------------------------ */ LOCAL void ciph_get_result (T_CIPH_out_data *out_data, U8 *status) { TRACE_FUNCTION( "ciph_get_result" ); switch(cci_data->fbs.ciph_params.direction) { case CIPH_UPLINK_DIR: if( *(cci_data->fbs.status_reg) & CHECK_WORKING ) { break; } else { ciph_get_ciphered_data (out_data); } break; case CIPH_DOWNLINK_DIR: if( *(cci_data->fbs.status_reg) & CHECK_WORKING ) { break; } else { ciph_get_deciphered_data (out_data, status); } break; default: TRACE_ERROR( "TIMER unexpected" ); break; } } /* ciph_get_result() */ /* +------------------------------------------------------------------------------ | Function : ciph_init +------------------------------------------------------------------------------ | Description : The function ciph_init() initializes the registers. | | Parameters : | +------------------------------------------------------------------------------ */ LOCAL void ciph_init ( void ) { USHORT *reg; TRACE_FUNCTION( "ciph_init" ); #ifdef _GEA_SIMULATION_ TRACE_EVENT ("GEA simulation is used"); /* * initialization of registers - do it only once to handle restart of CCI * 'hw_req' points to a set of 16 bit registers * 'fbs.simulated_reg_buffer' points to a 1596 bytes buffer for data */ if (hw_reg == NULL) { MALLOC(hw_reg, sizeof(USHORT) * 26+1 ); } memset(hw_reg, 0, sizeof(USHORT) * 26+1); if (cci_data->fbs.simulated_reg_buffer == NULL) { MALLOC(cci_data->fbs.simulated_reg_buffer, 1596); } memset(cci_data->fbs.simulated_reg_buffer, 0, 1596); reg = &hw_reg[0]; #else TRACE_EVENT ("GEA hardware is used"); reg = (USHORT *)START_ADRESS; #endif #if (BOARD == 61 OR BOARD == 71) /* G-Sample or I-Sample*/ /* 01 */ cci_data->fbs.cntl_reg = reg++; /* 00 */ /* 02 */ cci_data->fbs.status_reg = reg++; /* 02 */ /* 03 */ cci_data->fbs.status_irq_reg= reg++; /* 04 */ /* 04 */ cci_data->fbs.conf_ul_reg1 = reg++; /* 06 */ /* 05 */ cci_data->fbs.conf_ul_reg2 = reg++; /* 08 */ /* 06 */ cci_data->fbs.conf_ul_reg3 = reg++; /* 0A */ /* 07 */ cci_data->fbs.conf_ul_reg4 = reg++; /* 0C */ /* 08 */ cci_data->fbs.conf_ul_reg5 = reg++; /* 0E */ /* 09 */ cci_data->fbs.conf_dl_reg1 = reg++; /* 10 */ /* 10 */ cci_data->fbs.conf_dl_reg2 = reg++; /* 12 */ /* 11 */ cci_data->fbs.conf_dl_reg3 = reg++; /* 14 */ /* 12 */ cci_data->fbs.conf_dl_reg4 = reg++; /* 16 */ /* 13 */ cci_data->fbs.conf_dl_reg5 = reg++; /* 18 */ /* 14 */ cci_data->fbs.kc_reg1 = reg++; /* 1A */ /* 15 */ cci_data->fbs.kc_reg2 = reg++; /* 1C */ /* 16 */ cci_data->fbs.kc_reg3 = reg++; /* 1E */ /* 17 */ cci_data->fbs.kc_reg4 = reg++; /* 20 */ /* 22 */ reg++; /* 22 */ /* 22 */ reg++; /* 24 */ /* 22 */ reg++; /* 26 */ /* 22 */ reg++; /* 28 */ /* 18 */ cci_data->fbs.fcs_ul_reg1 = reg++; /* 2A */ /* 19 */ cci_data->fbs.fcs_ul_reg2 = reg++; /* 2C */ /* 20 */ cci_data->fbs.fcs_dl_reg1 = reg++; /* 2E */ /* 21 */ cci_data->fbs.fcs_dl_reg2 = reg++; /* 30 */ /* 22 */ cci_data->fbs.switch_reg = reg++; /* 32 */ /* 25 */ cci_data->fbs.data16_reg = reg++; /* 34 */ /* 26 */ cci_data->fbs.data8_reg = (UBYTE*)reg; /* 36 */ *cci_data->fbs.switch_reg = 0; #else /* 01 */ cci_data->fbs.cntl_reg = reg++; /* 00 */ /* 02 */ cci_data->fbs.status_reg = reg++; /* 02 */ /* 03 */ cci_data->fbs.status_irq_reg= reg++; /* 04 */ /* 04 */ cci_data->fbs.conf_ul_reg1 = reg++; /* 06 */ /* 05 */ cci_data->fbs.conf_ul_reg2 = reg++; /* 08 */ /* 06 */ cci_data->fbs.conf_ul_reg3 = reg++; /* 0A */ /* 07 */ cci_data->fbs.conf_ul_reg4 = reg++; /* 0C */ /* 08 */ cci_data->fbs.conf_ul_reg5 = reg++; /* 0E */ /* 09 */ cci_data->fbs.conf_dl_reg1 = reg++; /* 10 */ /* 10 */ cci_data->fbs.conf_dl_reg2 = reg++; /* 12 */ /* 11 */ cci_data->fbs.conf_dl_reg3 = reg++; /* 14 */ /* 12 */ cci_data->fbs.conf_dl_reg4 = reg++; /* 16 */ /* 13 */ cci_data->fbs.conf_dl_reg5 = reg++; /* 18 */ /* 14 */ cci_data->fbs.kc_reg1 = reg++; /* 1A */ /* 15 */ cci_data->fbs.kc_reg2 = reg++; /* 1C */ /* 16 */ cci_data->fbs.kc_reg3 = reg++; /* 1E */ /* 17 */ cci_data->fbs.kc_reg4 = reg++; /* 20 */ /* 18 */ cci_data->fbs.fcs_ul_reg1 = reg++; /* 22 */ /* 19 */ cci_data->fbs.fcs_ul_reg2 = reg++; /* 24 */ /* 20 */ cci_data->fbs.fcs_dl_reg1 = reg++; /* 26 */ /* 21 */ cci_data->fbs.fcs_dl_reg2 = reg++; /* 28 */ /* 22 */ reg++; /* 2A */ /* 23 */ reg++; /* 2C */ /* 24 */ reg++; /* 2E */ /* 25 */ cci_data->fbs.data16_reg = reg++; /* 30 */ /* 26 */ cci_data->fbs.data8_reg = (UBYTE*)reg; /* 32 */ #endif /* Board 61 or 71*/ #ifdef _GEA_SIMULATION_ cci_data->fbs.simulated_reg = cci_data->fbs.simulated_reg_buffer; #endif #ifndef _GEA_SIMULATION_ TRACE_EVENT ("Received FCS will be verified"); #endif /* finaly reset the HW */ ciph_reset_hw(); /* initialize flag for CCI info trace */ cci_data->fbs.cci_info_trace = FALSE; /* initialize freed partition counter */ cci_data->fbs.cci_freed_partition = 0; } /* ciph_init() */ /* +------------------------------------------------------------------------------ | Function : ciph_reset_hw +------------------------------------------------------------------------------ | Description : Resets the hardware | +------------------------------------------------------------------------------ */ LOCAL void ciph_reset_hw ( void ) { USHORT volatile *cntl = cci_data->fbs.cntl_reg; TRACE_FUNCTION( "ciph_reset_hw" ); /* making the clock enable */ *cntl |= CL_ENABLE; /* start reset in both directions and disable interrupt */ *cntl &= ~(RESET_UL | RESET_DL | IT_ENABLE); #ifdef _GEA_SIMULATION_ *cci_data->fbs.status_reg &= NOT_WORKING; /* simulate reset complete */ *cntl |= RESET_UL; *cntl |= RESET_DL; #endif /* wait until reset is ready (both bits back high) */ while ((*cntl & (RESET_UL|RESET_DL)) != (RESET_UL|RESET_DL)) ; /* disable clock until new frames are to process */ *cntl &= CL_DISABLE; } /* ciph_reset_hw() */ /* +------------------------------------------------------------------------------ | Function : ciph_fcs_check +------------------------------------------------------------------------------ | Description : The function compares the 3 bytes FCS for downlink direction | | Parameters : *fcs_start - pointer to beginning of fcs field | | Returns : CCI_FCS_PASSED - if equal | CCI_FCS_FAILED - if NOT equal +------------------------------------------------------------------------------ */ LOCAL UBYTE ciph_fcs_check (UBYTE* fcs_start) { TRACE_FUNCTION( "ciph_fcs_check" ); #ifdef _CHECK_RECEIVED_FCS_ #ifdef _GEA_SIMULATION_ /* * Compare FCS, taking byte ordering of FCS registers into account (Intel * format: high-/lowbyte swaped) */ if (* fcs_start == (UBYTE) (*cci_data->fbs.fcs_dl_reg1 & 0x00FF) && *(fcs_start+1) == (UBYTE)((*cci_data->fbs.fcs_dl_reg1 & 0xFF00) >> 8) && *(fcs_start+2) == (UBYTE) (*cci_data->fbs.fcs_dl_reg2 & 0x00FF) ) { /* clear bit to indicate FCS is ok */ *cci_data->fbs.status_reg &= ~(FCS_FALSE_BIT); } else { /* set bit to indicate FCS is false */ *cci_data->fbs.status_reg |= FCS_FALSE_BIT; } /* * Check, if FCS false bit is set */ if (*cci_data->fbs.status_reg & FCS_FALSE_BIT) { TRACE_EVENT("Info: Received FCS is wrong"); return CIPH_FCS_ERROR; } #endif /* _GEA_SIMULATION_ */ #endif /* _CHECK_RECEIVED_FCS_ */ #ifndef _GEA_SIMULATION_ /* * Check, if FCS false bit is set */ if (*cci_data->fbs.status_reg & FCS_FALSE_BIT) { TRACE_0_INFO("Received FCS is wrong"); return CIPH_FCS_ERROR; } #endif /* _GEA_SIMULATION_ */ return CIPH_CIPH_PASS; } /* ciph_fcs_check() */ /* +------------------------------------------------------------------------------ | Function : ciph_get_ciphered_data +------------------------------------------------------------------------------ | Description : The function ciph_get_ciphered_data() copies the result of the ciphered | data to destination buffer. | | Parameters : | +------------------------------------------------------------------------------ */ LOCAL void ciph_get_ciphered_data (T_CIPH_out_data *out_data) { int frame16, frame8, i; USHORT *sdu_data16; UBYTE *sdu_data8; TRACE_FUNCTION( "ciph_get_ciphered_data" ); i = out_data->len - FCS_SIZE; frame16 = i / 2; frame8 = i % 2; #ifdef _GEA_SIMULATION_ cci_data->fbs.simulated_reg = cci_data->fbs.simulated_reg_buffer; #endif /* _GEA_SIMULATION_ */ sdu_data16 = (USHORT*)out_data->buf; #if (BOARD == 61 OR BOARD == 71) /* G-Sample or I-Sample */ *cci_data->fbs.switch_reg = 1; #ifdef LLC_TRACE_GEA_PARAM cci_trace_gea_param(); #endif #endif for (i=0; i<frame16; i++) { #ifdef _GEA_SIMULATION_ ciph_reg16_read_sim(); #endif *sdu_data16 = *cci_data->fbs.data16_reg; sdu_data16++; } sdu_data8 = (UBYTE*)sdu_data16; if (frame8 != 0) { #ifdef _GEA_SIMULATION_ ciph_reg8_read_sim(); #endif *sdu_data8 = *cci_data->fbs.data8_reg; sdu_data8++; } #if (BOARD == 61 OR BOARD == 71) /* G-Sample or I-Sample */ *cci_data->fbs.switch_reg = 0; #endif /* * Copy FCS to destination sdu, taking byte ordering of FCS registers * into account, e.g.: * reg1 reg2 sdu * 29 FC xx 36 -> FC 29 36 */ *sdu_data8 = (UBYTE) (*cci_data->fbs.fcs_ul_reg1 & 0x00FF); sdu_data8++; *sdu_data8 = (UBYTE)((*cci_data->fbs.fcs_ul_reg1 & 0xFF00) >> 8); sdu_data8++; *sdu_data8 = (UBYTE) (*cci_data->fbs.fcs_ul_reg2 & 0x00FF); } /* ciph_get_ciphered_data() */ /* +------------------------------------------------------------------------------ | Function : ciph_get_deciphered_data +------------------------------------------------------------------------------ | Description : The function ciph_get_deciphered_data() .... | | Parameters : T_CCI_DECIPHER_CNF *decipher_cnf | +------------------------------------------------------------------------------ */ LOCAL void ciph_get_deciphered_data (T_CIPH_out_data *out_data, U8 *status) { int i, frame8, frame16; USHORT *sdu_data16; UBYTE *sdu_data8; TRACE_FUNCTION( "ciph_get_deciphered_data" ); i = out_data->len; frame16 = i / 2; frame8 = i % 2; #ifdef _GEA_SIMULATION_ cci_data->fbs.simulated_reg = cci_data->fbs.simulated_reg_buffer; #endif sdu_data16 = (USHORT*)out_data->buf; #if (BOARD == 61 OR BOARD == 71) /* G-Sample or I-Sample */ *cci_data->fbs.switch_reg = 1; #endif for (i=0; i<frame16; i++) { #ifdef _GEA_SIMULATION_ ciph_reg16_read_sim(); #endif *sdu_data16 = *cci_data->fbs.data16_reg; sdu_data16++; } sdu_data8 = (UBYTE*)sdu_data16; if (frame8 != 0) { #ifdef _GEA_SIMULATION_ ciph_reg8_read_sim(); #endif *sdu_data8 = *cci_data->fbs.data8_reg; sdu_data8++; } #if (BOARD == 61 OR BOARD == 71) /* G-Sample or I-Sample */ *cci_data->fbs.switch_reg = 0; #endif /* * Get result from FCS calculation */ *status = ciph_fcs_check(sdu_data8); } /* ciph_get_deciphered_data() */ /* +------------------------------------------------------------------------------ | Function : ciph_fill_ul_reg +------------------------------------------------------------------------------ | Description : The function ciph_fill_ul_reg() fills the uplink registers. | | Parameters : +------------------------------------------------------------------------------ */ LOCAL void ciph_fill_ul_reg ( T_CIPH_cipher_req_parms *cipher_req_parms, T_CIPH_in_data_list *in_data_list ) { int i, j; int frame8; UBYTE *desc_data8; U16 len = 0; TRACE_FUNCTION( "ciph_fill_ul_reg" ); /* * setting the protected mode variable */ if (cipher_req_parms->gprs_parameters.pm EQ CIPH_PM_PROTECTED) { *cci_data->fbs.conf_ul_reg1 |= PROTECTED; } else { *cci_data->fbs.conf_ul_reg1 &= NON_PROTECTED; } /* * FCS is always calculated */ *cci_data->fbs.conf_ul_reg1 |= FCS_COMPUTED; /* * direction is uplink */ /* Direction muss noch in init function gesetzt werden */ *cci_data->fbs.conf_ul_reg1 &= D_UL; if (cci_data->fbs.ciph_params.algo NEQ CIPH_EA0) { *cci_data->fbs.conf_ul_reg1 |= ENCRYPT; if(cci_data->fbs.ciph_params.algo EQ CIPH_EA1) { *cci_data->fbs.conf_ul_reg1 &= GEA_FIRST; } else if(cci_data->fbs.ciph_params.algo EQ CIPH_EA2) { *cci_data->fbs.conf_ul_reg1 |= GEA_SECOND; } else { TRACE_ERROR ("Illegal ciphering_algorithm"); } /* * if the condition is CCI_CIPHER_NO_ALGORITHM we don't use subsequent statements */ *cci_data->fbs.kc_reg1 = (USHORT)((USHORT)(cci_data->fbs.ciph_params.ptr_ck->ck_element[1]) << 8)+ (USHORT)(cci_data->fbs.ciph_params.ptr_ck->ck_element[0]); *cci_data->fbs.kc_reg2 = (USHORT)((USHORT)(cci_data->fbs.ciph_params.ptr_ck->ck_element[3]) << 8)+ (USHORT)(cci_data->fbs.ciph_params.ptr_ck->ck_element[2]); *cci_data->fbs.kc_reg3 = (USHORT)((USHORT)(cci_data->fbs.ciph_params.ptr_ck->ck_element[5]) << 8)+ (USHORT)(cci_data->fbs.ciph_params.ptr_ck->ck_element[4]); *cci_data->fbs.kc_reg4 = (USHORT)((USHORT)(cci_data->fbs.ciph_params.ptr_ck->ck_element[7]) << 8)+ (USHORT)(cci_data->fbs.ciph_params.ptr_ck->ck_element[6]); /* store ciphering key in the local buffer for later verification */ if(cci_data->fbs.cci_info_trace){ tmp_key[0] = *cci_data->fbs.kc_reg1; tmp_key[1] = *cci_data->fbs.kc_reg2; tmp_key[2] = *cci_data->fbs.kc_reg3; tmp_key[3] = *cci_data->fbs.kc_reg4; } /* * FRAME DEPENDENT CIPHERING INPUT entity is ULONG in the primitive */ *cci_data->fbs.conf_ul_reg4 = (USHORT)(cipher_req_parms->gprs_parameters.ciphering_input); *cci_data->fbs.conf_ul_reg5 = (USHORT)(cipher_req_parms->gprs_parameters.ciphering_input >> 16); /* * it is assumed that MSB is first 16 bit and LSB part is last 16 bits */ } else { /* * in this case we don't fill the registers that contain ciphering keys */ *cci_data->fbs.conf_ul_reg1 &= NO_ENCRYPT; } /* * Enter LLC-PDU size in bytes */ for (i = 0; i < in_data_list->c_in_data; i++) { len += in_data_list->ptr_in_data[i].len; } *cci_data->fbs.conf_ul_reg2 = (USHORT)len; /* * conf_ul_reg3 is seperated into 2 parts of UBYTE: * -> lowbyte = N202 * -> hightbyte = LLC-PDU header size in bytes (indicate the offset of information) */ *cci_data->fbs.conf_ul_reg3 = (USHORT)((cipher_req_parms->gprs_parameters.header_size << 8) | CIPH_N202); #ifdef _GEA_SIMULATION_ cci_data->fbs.simulated_reg = cci_data->fbs.simulated_reg_buffer; #endif *cci_data->fbs.conf_ul_reg1 &= NO_INPUT_SHIFT; #if (BOARD == 61 OR BOARD == 71) /* G-Sample or I-Sample */ *cci_data->fbs.switch_reg = 1; #ifdef LLC_TRACE_GEA_PARAM cci_trace_gea_param(); #endif #endif for (i = 0; i < in_data_list->c_in_data; i++) { desc_data8 = (U8*)in_data_list->ptr_in_data[i].buf; frame8 = in_data_list->ptr_in_data[i].len; for (j=0; j < frame8; j++) { *cci_data->fbs.data8_reg = *desc_data8; #ifdef _GEA_SIMULATION_ ciph_reg8_write_sim(); #endif desc_data8++; } } #if (BOARD == 61 OR BOARD == 71) /* G-Sample or I-Sample */ *cci_data->fbs.switch_reg = 0; #endif } /* ciph_fill_ul_reg() */ /* +------------------------------------------------------------------------------ | Function : ciph_fill_dl_reg +------------------------------------------------------------------------------ | Description : The function ciph_fill_dl_reg() | | Parameters : | +------------------------------------------------------------------------------ */ LOCAL void ciph_fill_dl_reg (T_CIPH_cipher_req_parms *cipher_req_parms, T_CIPH_in_data_list *in_data_list ) { ULONG i, j; ULONG frame8; UBYTE *desc_data8; ULONG len = 0; TRACE_FUNCTION( "ciph_fill_dl_reg" ); /* * setting the protected mode variable */ if(cipher_req_parms->gprs_parameters.pm EQ CIPH_PM_PROTECTED) { *cci_data->fbs.conf_dl_reg1 |= PROTECTED; } else { *cci_data->fbs.conf_dl_reg1 &= NON_PROTECTED; } /* * FCS is always calculated */ *cci_data->fbs.conf_dl_reg1 |= FCS_COMPUTED; /* * data always copied aligned independent */ *cci_data->fbs.conf_dl_reg1 &= NO_INPUT_SHIFT; /* * direction is downlink */ *cci_data->fbs.conf_dl_reg1 |= D_DL; if(cci_data->fbs.ciph_params.algo NEQ CIPH_EA0) { *cci_data->fbs.conf_dl_reg1 |= ENCRYPT; if(cci_data->fbs.ciph_params.algo EQ CIPH_EA1) { *cci_data->fbs.conf_dl_reg1 &= GEA_FIRST; } else if(cci_data->fbs.ciph_params.algo EQ CIPH_EA2) { *cci_data->fbs.conf_dl_reg1 |= GEA_SECOND; } else { TRACE_ERROR ("Illegal ciphering_algorithm"); } *cci_data->fbs.kc_reg1 = (USHORT)((USHORT)(cci_data->fbs.ciph_params.ptr_ck->ck_element[1]) << 8) + (USHORT)(cci_data->fbs.ciph_params.ptr_ck->ck_element[0]); *cci_data->fbs.kc_reg2 = (USHORT)((USHORT)(cci_data->fbs.ciph_params.ptr_ck->ck_element[3]) << 8) + (USHORT)(cci_data->fbs.ciph_params.ptr_ck->ck_element[2]); *cci_data->fbs.kc_reg3 = (USHORT)((USHORT)(cci_data->fbs.ciph_params.ptr_ck->ck_element[5]) << 8) + (USHORT)(cci_data->fbs.ciph_params.ptr_ck->ck_element[4]); *cci_data->fbs.kc_reg4 = (USHORT)((USHORT)(cci_data->fbs.ciph_params.ptr_ck->ck_element[7]) << 8) + (USHORT)(cci_data->fbs.ciph_params.ptr_ck->ck_element[6]); /* store ciphering key in local buffer for later verification */ if(cci_data->fbs.cci_info_trace){ tmp_key[0] = *cci_data->fbs.kc_reg1; tmp_key[1] = *cci_data->fbs.kc_reg2; tmp_key[2] = *cci_data->fbs.kc_reg3; tmp_key[3] = *cci_data->fbs.kc_reg4; } /* * FRAME DEPENDENT CIPHERING INPUT entity is ULONG in the primitive */ *cci_data->fbs.conf_dl_reg4 = (USHORT)(cipher_req_parms->gprs_parameters.ciphering_input); *cci_data->fbs.conf_dl_reg5 = (USHORT)(cipher_req_parms->gprs_parameters.ciphering_input >> 16); } else { /* * in this case we don't fill the registers that contain ciphering keys */ *cci_data->fbs.conf_dl_reg1 &= NO_ENCRYPT; } /* * Write length of LLC-PDU in bytes including FCS */ for (i = 0; i < in_data_list->c_in_data; i++) { len += in_data_list->ptr_in_data[i].len; } *cci_data->fbs.conf_dl_reg2 = (USHORT)len; /* * conf_dl_reg3 is seperated into 2 parts of UBYTE: * -> lowbyte = N202 * -> hightbyte = LLC-PDU header size in bytes (indicate the offset of information) */ *cci_data->fbs.conf_dl_reg3 = (USHORT)((cipher_req_parms->gprs_parameters.header_size << 8) | CIPH_N202); #ifdef _GEA_SIMULATION_ cci_data->fbs.simulated_reg = cci_data->fbs.simulated_reg_buffer; #endif #if (BOARD == 61 OR BOARD == 71) /* G-Sample or I-Sample */ *cci_data->fbs.switch_reg = 1; #endif for (i = 0; i < in_data_list->c_in_data; i++) { desc_data8 = (UBYTE*)in_data_list->ptr_in_data[i].buf; frame8 = in_data_list->ptr_in_data[i].len; for (j=0; j < frame8; j++){ *cci_data->fbs.data8_reg = desc_data8[j]; #ifdef _GEA_SIMULATION_ ciph_reg8_write_sim(); #endif } } #if (BOARD == 61 OR BOARD == 71) /* G-Sample or I-Sample */ *cci_data->fbs.switch_reg = 0; #endif } /* ciph_fill_dl_reg() */ #if (BOARD == 61 OR BOARD == 71) /* G-Sample or I-Sample */ #ifdef LLC_TRACE_GEA_PARAM LOCAL void cci_trace_gea_param( void ) { TRACE_EVENT_P9( "cci_trace_gea_param_1 %04X %04X %04X %04X %04X %04X %04X %04X %04X", *cci_data->fbs.cntl_reg , *cci_data->fbs.status_reg , *cci_data->fbs.status_irq_reg, *cci_data->fbs.conf_ul_reg1 , *cci_data->fbs.conf_ul_reg2 , *cci_data->fbs.conf_ul_reg3 , *cci_data->fbs.conf_ul_reg4 , *cci_data->fbs.conf_ul_reg5 , *cci_data->fbs.conf_dl_reg1 ); TRACE_EVENT_P9( "cci_trace_gea_param_2 %04X %04X %04X %04X %04X %04X %04X %04X %04X", *cci_data->fbs.conf_dl_reg2 , *cci_data->fbs.conf_dl_reg3 , *cci_data->fbs.conf_dl_reg4 , *cci_data->fbs.conf_dl_reg5 , *cci_data->fbs.fcs_ul_reg1 , *cci_data->fbs.fcs_ul_reg2 , *cci_data->fbs.fcs_dl_reg1 , *cci_data->fbs.fcs_dl_reg2 , *cci_data->fbs.switch_reg ); } #endif #endif #endif /* TI_PS_OP_CIPH_DRIVER */