FreeCalypso > hg > fc-magnetite
comparison src/g23m-gprs/cci/cci_fbsf.c @ 183:219afcfc6250
src/g23m-gprs: initial import from TCS3.2/LoCosto
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 13 Oct 2016 04:24:13 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
182:f02d0a0e1849 | 183:219afcfc6250 |
---|---|
1 /* | |
2 +----------------------------------------------------------------------------- | |
3 | Project : | |
4 | Modul : cci_fbsf.c | |
5 +----------------------------------------------------------------------------- | |
6 | Copyright 2002 Texas Instruments Berlin, AG | |
7 | All rights reserved. | |
8 | | |
9 | This file is confidential and a trade secret of Texas | |
10 | Instruments Berlin, AG | |
11 | The receipt of or possession of this file does not convey | |
12 | any rights to reproduce or disclose its contents or to | |
13 | manufacture, use, or sell anything it may describe, in | |
14 | whole, or in part, without the specific written consent of | |
15 | Texas Instruments Berlin, AG. | |
16 +----------------------------------------------------------------------------- | |
17 | Purpose : This module implements local functions for service FBS of | |
18 | entity CCI. | |
19 +----------------------------------------------------------------------------- | |
20 */ | |
21 | |
22 | |
23 #define CCI_FBSF_C | |
24 | |
25 #define ENTITY_LLC | |
26 | |
27 /*==== INCLUDES =============================================================*/ | |
28 #include <string.h> | |
29 | |
30 #include "typedefs.h" /* to get Condat data types */ | |
31 #include "vsi.h" /* to get a lot of macros */ | |
32 #include "macdef.h" | |
33 #include "gprs.h" | |
34 #include "gsm.h" /* to get a lot of macros */ | |
35 #include "cnf_llc.h" /* to get cnf-definitions */ | |
36 #include "mon_llc.h" /* to get mon-definitions */ | |
37 #include "prim.h" /* to get the definitions of used SAP and directions */ | |
38 #include "cci.h" /* to get the global entity definitions */ | |
39 #include "llc.h" /* to get the global entity definitions */ | |
40 | |
41 #include "cci_fbsf.h" | |
42 #include "llc_txp.h" | |
43 #include "llc_rxp.h" | |
44 | |
45 #ifndef TI_PS_OP_CIPH_DRIVER | |
46 | |
47 #ifdef _GEA_SIMULATION_ | |
48 #include "cci_hw_sim.h" | |
49 #endif | |
50 | |
51 #if !defined(_GEA_SIMULATION_) && !defined(LL_2to1) | |
52 #include "config/chipset.cfg" | |
53 #if (CHIPSET == 12) || (CHIPSET == 14) | |
54 #include "cci_gea_start.h" | |
55 #endif /* CHIPSET */ | |
56 #endif /* ! _GEA_SIMULATION_ && !LL_2to1 */ | |
57 | |
58 /* local buffer for the copy of ciphering key */ | |
59 static USHORT tmp_key[4]; | |
60 | |
61 | |
62 | |
63 /*==== CONST ================================================================*/ | |
64 | |
65 /*==== LOCAL VARS ===========================================================*/ | |
66 #ifdef _GEA_SIMULATION_ | |
67 USHORT* hw_reg = NULL; | |
68 #endif | |
69 | |
70 /*==== LOCAL FUNCTION ===========================================================*/ | |
71 | |
72 LOCAL void ciph_get_result (T_CIPH_out_data *out_data, U8 *status); | |
73 LOCAL void ciph_init (void); | |
74 LOCAL void ciph_reset_hw (void); | |
75 LOCAL UBYTE ciph_fcs_check (UBYTE *fcs_start); | |
76 LOCAL void ciph_get_ciphered_data (T_CIPH_out_data *out_data); | |
77 LOCAL void ciph_get_deciphered_data (T_CIPH_out_data *out_data, U8 *status); | |
78 LOCAL void ciph_fill_ul_reg (T_CIPH_cipher_req_parms *cipher_req_parms, | |
79 T_CIPH_in_data_list *in_data_list); | |
80 LOCAL void ciph_fill_dl_reg (T_CIPH_cipher_req_parms *cipher_req_parms, | |
81 T_CIPH_in_data_list *in_data_list); | |
82 | |
83 /*==== PRIVATE FUNCTIONS ====================================================*/ | |
84 | |
85 #ifdef LLC_TRACE_GEA_PARAM | |
86 LOCAL void cci_trace_gea_param( void ); | |
87 #endif | |
88 | |
89 /*==== PUBLIC FUNCTIONS =====================================================*/ | |
90 | |
91 /* | |
92 +------------------------------------------------------------------------------ | |
93 | Function : ciph_cipher_req_sim | |
94 +------------------------------------------------------------------------------ | |
95 | Description : Handles the primitive ciph_cipher_req. It is used to request | |
96 | ciphering or deciphering of a LLC PDU. | |
97 | | |
98 | Parameters : | |
99 | | |
100 +------------------------------------------------------------------------------ | |
101 */ | |
102 GLOBAL void ciph_cipher_req_sim (T_CIPH_cipher_req_parms *cipher_req_parms_ptr, | |
103 T_CIPH_in_data_list *in_data_ptr, | |
104 T_CIPH_out_data *out_data_ptr, | |
105 U8 *status) { | |
106 | |
107 USHORT volatile *cntl = cci_data->fbs.cntl_reg; | |
108 int i = 0; | |
109 ULONG cnt = 0; | |
110 | |
111 | |
112 TRACE_FUNCTION( "ciph_cipher_req" ); | |
113 | |
114 /* reset GEA (enables and then disables clock) */ | |
115 ciph_reset_hw(); | |
116 | |
117 *cntl |= CL_ENABLE; | |
118 | |
119 /* fill UL or DL configuration and data registers */ | |
120 | |
121 if (cci_data->fbs.ciph_params.direction == CIPH_UPLINK_DIR) { | |
122 ciph_fill_ul_reg (cipher_req_parms_ptr, in_data_ptr ); | |
123 #ifdef LL_2to1 | |
124 *cntl = (*cntl & UL_DL_UP) | START; | |
125 #else /* LL_2to1 */ | |
126 #if (CHIPSET == 12) || (CHIPSET == 14) | |
127 /* GEA work-around */ | |
128 *cntl = (*cntl & UL_DL_UP); | |
129 gea_start(); | |
130 #else | |
131 *cntl = (*cntl & UL_DL_UP) | START; | |
132 #endif | |
133 #endif /* LL_2to1 */ | |
134 } else { | |
135 ciph_fill_dl_reg (cipher_req_parms_ptr, in_data_ptr ); | |
136 #ifdef LL_2to1 | |
137 *cntl |= (UL_DL_DOWN | START); | |
138 #else /* LL_2to1 */ | |
139 #if (CHIPSET == 12) || (CHIPSET == 14) | |
140 /* GEA work-around */ | |
141 *cntl |= (UL_DL_DOWN); | |
142 gea_start(); | |
143 #else | |
144 *cntl |= (UL_DL_DOWN | START); | |
145 #endif | |
146 #endif /* LL_2to1 */ | |
147 } | |
148 | |
149 out_data_ptr->len = 0; | |
150 for (i = 0; i < in_data_ptr->c_in_data; i++) { | |
151 out_data_ptr->len += in_data_ptr->ptr_in_data[i].len; | |
152 } | |
153 | |
154 if (cci_data->fbs.ciph_params.direction == CIPH_DOWNLINK_DIR) { | |
155 out_data_ptr->len -= FCS_SIZE; | |
156 } else { | |
157 out_data_ptr->len += FCS_SIZE; | |
158 } | |
159 | |
160 | |
161 #ifdef _GEA_SIMULATION_ | |
162 if (cci_data->fbs.ciph_params.direction == CIPH_UPLINK_DIR) { | |
163 ciph_hw_sim_cipher(out_data_ptr->len); | |
164 } else { | |
165 ciph_hw_sim_decipher(); | |
166 } | |
167 #endif | |
168 | |
169 /* poll until data is processed */ | |
170 if(cci_data->fbs.cci_info_trace){ | |
171 while (*(cci_data->fbs.status_reg) & CHECK_WORKING){ | |
172 cnt += 1; | |
173 }; | |
174 TRACE_EVENT_P1("INFO CCI: ciphering completed, counter: %d", cnt); | |
175 } else { | |
176 while (*(cci_data->fbs.status_reg) & CHECK_WORKING){ }; | |
177 } | |
178 | |
179 /* verify ciphering key, whether it has been corrupted */ | |
180 if(cci_data->fbs.cci_info_trace){ | |
181 if(*cci_data->fbs.kc_reg1 != tmp_key[0] || | |
182 *cci_data->fbs.kc_reg2 != tmp_key[1] || | |
183 *cci_data->fbs.kc_reg3 != tmp_key[2] || | |
184 *cci_data->fbs.kc_reg4 != tmp_key[3]) | |
185 { | |
186 TRACE_ERROR("CCI ERROR: Ciphering key has been corrupted!!"); | |
187 TRACE_EVENT_P4("CCI: original key: %04x %04x %04x %04x %04x %04x", | |
188 tmp_key[0], tmp_key[1], tmp_key[2], tmp_key[3]); | |
189 TRACE_EVENT_P4("CCI: kc key: %04x %04x %04x %04x %04x %04x", | |
190 *cci_data->fbs.kc_reg1, *cci_data->fbs.kc_reg2, | |
191 *cci_data->fbs.kc_reg3, *cci_data->fbs.kc_reg4); | |
192 } | |
193 } | |
194 | |
195 /* and finally handle the result */ | |
196 ciph_get_result(out_data_ptr, status); | |
197 | |
198 /* disable clock until new frames are to process */ | |
199 *cntl &= CL_DISABLE; | |
200 | |
201 } | |
202 | |
203 | |
204 /* | |
205 +------------------------------------------------------------------------------ | |
206 | Function : ciph_init_cipher_req_sim | |
207 +------------------------------------------------------------------------------ | |
208 | Description : Handles the primitive ciph_init_cipher_req_sim. | |
209 | | |
210 | Parameters : | |
211 | | |
212 +------------------------------------------------------------------------------ | |
213 */ | |
214 GLOBAL void ciph_init_cipher_req_sim (T_CIPH_init_cipher_req_parms *init_cipher_req_parms_ptr, | |
215 void (*read_data) (void)) | |
216 { | |
217 if (!cci_data->fbs.initialized){ | |
218 ciph_init(); | |
219 cci_data->fbs.initialized = TRUE; | |
220 } | |
221 cci_data->fbs.ciph_params = *init_cipher_req_parms_ptr; | |
222 } | |
223 | |
224 /* | |
225 +------------------------------------------------------------------------------ | |
226 | Function : ciph_get_result | |
227 +------------------------------------------------------------------------------ | |
228 | Description : Handles the function ciph_get_result. This function gets the | |
229 | ciphered data in uplink direction or deciphered data in | |
230 | downlink direction | |
231 | | |
232 | Parameters : | |
233 +------------------------------------------------------------------------------ | |
234 */ | |
235 LOCAL void ciph_get_result (T_CIPH_out_data *out_data, U8 *status) | |
236 { | |
237 TRACE_FUNCTION( "ciph_get_result" ); | |
238 | |
239 switch(cci_data->fbs.ciph_params.direction) | |
240 { | |
241 case CIPH_UPLINK_DIR: | |
242 if( *(cci_data->fbs.status_reg) & CHECK_WORKING ) | |
243 { | |
244 break; | |
245 } | |
246 else | |
247 { | |
248 ciph_get_ciphered_data (out_data); | |
249 } | |
250 break; | |
251 | |
252 case CIPH_DOWNLINK_DIR: | |
253 if( *(cci_data->fbs.status_reg) & CHECK_WORKING ) | |
254 { | |
255 break; | |
256 } | |
257 else | |
258 { | |
259 ciph_get_deciphered_data (out_data, status); | |
260 } | |
261 break; | |
262 | |
263 default: | |
264 TRACE_ERROR( "TIMER unexpected" ); | |
265 break; | |
266 } | |
267 | |
268 } /* ciph_get_result() */ | |
269 | |
270 | |
271 /* | |
272 +------------------------------------------------------------------------------ | |
273 | Function : ciph_init | |
274 +------------------------------------------------------------------------------ | |
275 | Description : The function ciph_init() initializes the registers. | |
276 | | |
277 | Parameters : | |
278 | | |
279 +------------------------------------------------------------------------------ | |
280 */ | |
281 LOCAL void ciph_init ( void ) | |
282 { | |
283 USHORT *reg; | |
284 | |
285 TRACE_FUNCTION( "ciph_init" ); | |
286 | |
287 | |
288 #ifdef _GEA_SIMULATION_ | |
289 | |
290 TRACE_EVENT ("GEA simulation is used"); | |
291 | |
292 /* | |
293 * initialization of registers - do it only once to handle restart of CCI | |
294 * 'hw_req' points to a set of 16 bit registers | |
295 * 'fbs.simulated_reg_buffer' points to a 1596 bytes buffer for data | |
296 */ | |
297 if (hw_reg == NULL) | |
298 { | |
299 MALLOC(hw_reg, sizeof(USHORT) * 26+1 ); | |
300 } | |
301 memset(hw_reg, 0, sizeof(USHORT) * 26+1); | |
302 | |
303 if (cci_data->fbs.simulated_reg_buffer == NULL) | |
304 { | |
305 MALLOC(cci_data->fbs.simulated_reg_buffer, 1596); | |
306 } | |
307 memset(cci_data->fbs.simulated_reg_buffer, 0, 1596); | |
308 | |
309 reg = &hw_reg[0]; | |
310 | |
311 #else | |
312 | |
313 TRACE_EVENT ("GEA hardware is used"); | |
314 | |
315 reg = (USHORT *)START_ADRESS; | |
316 | |
317 #endif | |
318 | |
319 #if (BOARD == 61 OR BOARD == 71) /* G-Sample or I-Sample*/ | |
320 | |
321 /* 01 */ cci_data->fbs.cntl_reg = reg++; /* 00 */ | |
322 /* 02 */ cci_data->fbs.status_reg = reg++; /* 02 */ | |
323 /* 03 */ cci_data->fbs.status_irq_reg= reg++; /* 04 */ | |
324 | |
325 /* 04 */ cci_data->fbs.conf_ul_reg1 = reg++; /* 06 */ | |
326 /* 05 */ cci_data->fbs.conf_ul_reg2 = reg++; /* 08 */ | |
327 /* 06 */ cci_data->fbs.conf_ul_reg3 = reg++; /* 0A */ | |
328 /* 07 */ cci_data->fbs.conf_ul_reg4 = reg++; /* 0C */ | |
329 /* 08 */ cci_data->fbs.conf_ul_reg5 = reg++; /* 0E */ | |
330 | |
331 /* 09 */ cci_data->fbs.conf_dl_reg1 = reg++; /* 10 */ | |
332 /* 10 */ cci_data->fbs.conf_dl_reg2 = reg++; /* 12 */ | |
333 /* 11 */ cci_data->fbs.conf_dl_reg3 = reg++; /* 14 */ | |
334 /* 12 */ cci_data->fbs.conf_dl_reg4 = reg++; /* 16 */ | |
335 /* 13 */ cci_data->fbs.conf_dl_reg5 = reg++; /* 18 */ | |
336 | |
337 /* 14 */ cci_data->fbs.kc_reg1 = reg++; /* 1A */ | |
338 /* 15 */ cci_data->fbs.kc_reg2 = reg++; /* 1C */ | |
339 /* 16 */ cci_data->fbs.kc_reg3 = reg++; /* 1E */ | |
340 /* 17 */ cci_data->fbs.kc_reg4 = reg++; /* 20 */ | |
341 | |
342 /* 22 */ reg++; /* 22 */ | |
343 /* 22 */ reg++; /* 24 */ | |
344 /* 22 */ reg++; /* 26 */ | |
345 /* 22 */ reg++; /* 28 */ | |
346 | |
347 /* 18 */ cci_data->fbs.fcs_ul_reg1 = reg++; /* 2A */ | |
348 /* 19 */ cci_data->fbs.fcs_ul_reg2 = reg++; /* 2C */ | |
349 | |
350 /* 20 */ cci_data->fbs.fcs_dl_reg1 = reg++; /* 2E */ | |
351 /* 21 */ cci_data->fbs.fcs_dl_reg2 = reg++; /* 30 */ | |
352 | |
353 /* 22 */ cci_data->fbs.switch_reg = reg++; /* 32 */ | |
354 | |
355 /* 25 */ cci_data->fbs.data16_reg = reg++; /* 34 */ | |
356 /* 26 */ cci_data->fbs.data8_reg = (UBYTE*)reg; /* 36 */ | |
357 | |
358 *cci_data->fbs.switch_reg = 0; | |
359 | |
360 #else | |
361 | |
362 /* 01 */ cci_data->fbs.cntl_reg = reg++; /* 00 */ | |
363 /* 02 */ cci_data->fbs.status_reg = reg++; /* 02 */ | |
364 /* 03 */ cci_data->fbs.status_irq_reg= reg++; /* 04 */ | |
365 | |
366 /* 04 */ cci_data->fbs.conf_ul_reg1 = reg++; /* 06 */ | |
367 /* 05 */ cci_data->fbs.conf_ul_reg2 = reg++; /* 08 */ | |
368 /* 06 */ cci_data->fbs.conf_ul_reg3 = reg++; /* 0A */ | |
369 /* 07 */ cci_data->fbs.conf_ul_reg4 = reg++; /* 0C */ | |
370 /* 08 */ cci_data->fbs.conf_ul_reg5 = reg++; /* 0E */ | |
371 | |
372 /* 09 */ cci_data->fbs.conf_dl_reg1 = reg++; /* 10 */ | |
373 /* 10 */ cci_data->fbs.conf_dl_reg2 = reg++; /* 12 */ | |
374 /* 11 */ cci_data->fbs.conf_dl_reg3 = reg++; /* 14 */ | |
375 /* 12 */ cci_data->fbs.conf_dl_reg4 = reg++; /* 16 */ | |
376 /* 13 */ cci_data->fbs.conf_dl_reg5 = reg++; /* 18 */ | |
377 | |
378 /* 14 */ cci_data->fbs.kc_reg1 = reg++; /* 1A */ | |
379 /* 15 */ cci_data->fbs.kc_reg2 = reg++; /* 1C */ | |
380 /* 16 */ cci_data->fbs.kc_reg3 = reg++; /* 1E */ | |
381 /* 17 */ cci_data->fbs.kc_reg4 = reg++; /* 20 */ | |
382 | |
383 /* 18 */ cci_data->fbs.fcs_ul_reg1 = reg++; /* 22 */ | |
384 /* 19 */ cci_data->fbs.fcs_ul_reg2 = reg++; /* 24 */ | |
385 | |
386 /* 20 */ cci_data->fbs.fcs_dl_reg1 = reg++; /* 26 */ | |
387 /* 21 */ cci_data->fbs.fcs_dl_reg2 = reg++; /* 28 */ | |
388 | |
389 /* 22 */ reg++; /* 2A */ | |
390 /* 23 */ reg++; /* 2C */ | |
391 /* 24 */ reg++; /* 2E */ | |
392 | |
393 /* 25 */ cci_data->fbs.data16_reg = reg++; /* 30 */ | |
394 /* 26 */ cci_data->fbs.data8_reg = (UBYTE*)reg; /* 32 */ | |
395 #endif /* Board 61 or 71*/ | |
396 | |
397 #ifdef _GEA_SIMULATION_ | |
398 cci_data->fbs.simulated_reg = cci_data->fbs.simulated_reg_buffer; | |
399 #endif | |
400 | |
401 #ifndef _GEA_SIMULATION_ | |
402 TRACE_EVENT ("Received FCS will be verified"); | |
403 #endif | |
404 | |
405 /* finaly reset the HW */ | |
406 ciph_reset_hw(); | |
407 | |
408 /* initialize flag for CCI info trace */ | |
409 cci_data->fbs.cci_info_trace = FALSE; | |
410 /* initialize freed partition counter */ | |
411 cci_data->fbs.cci_freed_partition = 0; | |
412 | |
413 } /* ciph_init() */ | |
414 | |
415 | |
416 /* | |
417 +------------------------------------------------------------------------------ | |
418 | Function : ciph_reset_hw | |
419 +------------------------------------------------------------------------------ | |
420 | Description : Resets the hardware | |
421 | | |
422 +------------------------------------------------------------------------------ | |
423 */ | |
424 LOCAL void ciph_reset_hw ( void ) | |
425 { | |
426 USHORT volatile *cntl = cci_data->fbs.cntl_reg; | |
427 | |
428 TRACE_FUNCTION( "ciph_reset_hw" ); | |
429 | |
430 /* making the clock enable */ | |
431 *cntl |= CL_ENABLE; | |
432 | |
433 /* start reset in both directions and disable interrupt */ | |
434 *cntl &= ~(RESET_UL | RESET_DL | IT_ENABLE); | |
435 | |
436 #ifdef _GEA_SIMULATION_ | |
437 | |
438 *cci_data->fbs.status_reg &= NOT_WORKING; | |
439 | |
440 /* simulate reset complete */ | |
441 *cntl |= RESET_UL; | |
442 *cntl |= RESET_DL; | |
443 | |
444 #endif | |
445 | |
446 /* wait until reset is ready (both bits back high) */ | |
447 while ((*cntl & (RESET_UL|RESET_DL)) != (RESET_UL|RESET_DL)) | |
448 ; | |
449 | |
450 /* disable clock until new frames are to process */ | |
451 *cntl &= CL_DISABLE; | |
452 | |
453 } /* ciph_reset_hw() */ | |
454 | |
455 /* | |
456 +------------------------------------------------------------------------------ | |
457 | Function : ciph_fcs_check | |
458 +------------------------------------------------------------------------------ | |
459 | Description : The function compares the 3 bytes FCS for downlink direction | |
460 | | |
461 | Parameters : *fcs_start - pointer to beginning of fcs field | |
462 | | |
463 | Returns : CCI_FCS_PASSED - if equal | |
464 | CCI_FCS_FAILED - if NOT equal | |
465 +------------------------------------------------------------------------------ | |
466 */ | |
467 LOCAL UBYTE ciph_fcs_check (UBYTE* fcs_start) | |
468 { | |
469 TRACE_FUNCTION( "ciph_fcs_check" ); | |
470 | |
471 #ifdef _CHECK_RECEIVED_FCS_ | |
472 #ifdef _GEA_SIMULATION_ | |
473 /* | |
474 * Compare FCS, taking byte ordering of FCS registers into account (Intel | |
475 * format: high-/lowbyte swaped) | |
476 */ | |
477 if (* fcs_start == (UBYTE) (*cci_data->fbs.fcs_dl_reg1 & 0x00FF) && | |
478 *(fcs_start+1) == (UBYTE)((*cci_data->fbs.fcs_dl_reg1 & 0xFF00) >> 8) && | |
479 *(fcs_start+2) == (UBYTE) (*cci_data->fbs.fcs_dl_reg2 & 0x00FF) ) | |
480 { | |
481 /* clear bit to indicate FCS is ok */ | |
482 *cci_data->fbs.status_reg &= ~(FCS_FALSE_BIT); | |
483 } | |
484 else | |
485 { | |
486 /* set bit to indicate FCS is false */ | |
487 *cci_data->fbs.status_reg |= FCS_FALSE_BIT; | |
488 } | |
489 | |
490 /* | |
491 * Check, if FCS false bit is set | |
492 */ | |
493 if (*cci_data->fbs.status_reg & FCS_FALSE_BIT) | |
494 { | |
495 TRACE_EVENT("Info: Received FCS is wrong"); | |
496 return CIPH_FCS_ERROR; | |
497 } | |
498 #endif /* _GEA_SIMULATION_ */ | |
499 #endif /* _CHECK_RECEIVED_FCS_ */ | |
500 | |
501 | |
502 #ifndef _GEA_SIMULATION_ | |
503 /* | |
504 * Check, if FCS false bit is set | |
505 */ | |
506 if (*cci_data->fbs.status_reg & FCS_FALSE_BIT) | |
507 { | |
508 TRACE_0_INFO("Received FCS is wrong"); | |
509 return CIPH_FCS_ERROR; | |
510 } | |
511 #endif /* _GEA_SIMULATION_ */ | |
512 | |
513 return CIPH_CIPH_PASS; | |
514 | |
515 } /* ciph_fcs_check() */ | |
516 | |
517 | |
518 /* | |
519 +------------------------------------------------------------------------------ | |
520 | Function : ciph_get_ciphered_data | |
521 +------------------------------------------------------------------------------ | |
522 | Description : The function ciph_get_ciphered_data() copies the result of the ciphered | |
523 | data to destination buffer. | |
524 | | |
525 | Parameters : | |
526 | | |
527 +------------------------------------------------------------------------------ | |
528 */ | |
529 LOCAL void ciph_get_ciphered_data (T_CIPH_out_data *out_data) | |
530 { | |
531 int frame16, | |
532 frame8, | |
533 i; | |
534 USHORT *sdu_data16; | |
535 UBYTE *sdu_data8; | |
536 | |
537 TRACE_FUNCTION( "ciph_get_ciphered_data" ); | |
538 | |
539 i = out_data->len - FCS_SIZE; | |
540 | |
541 frame16 = i / 2; | |
542 frame8 = i % 2; | |
543 | |
544 #ifdef _GEA_SIMULATION_ | |
545 cci_data->fbs.simulated_reg = cci_data->fbs.simulated_reg_buffer; | |
546 #endif /* _GEA_SIMULATION_ */ | |
547 | |
548 sdu_data16 = (USHORT*)out_data->buf; | |
549 | |
550 #if (BOARD == 61 OR BOARD == 71) /* G-Sample or I-Sample */ | |
551 *cci_data->fbs.switch_reg = 1; | |
552 | |
553 #ifdef LLC_TRACE_GEA_PARAM | |
554 cci_trace_gea_param(); | |
555 #endif | |
556 | |
557 #endif | |
558 | |
559 for (i=0; i<frame16; i++) | |
560 { | |
561 | |
562 #ifdef _GEA_SIMULATION_ | |
563 ciph_reg16_read_sim(); | |
564 #endif | |
565 | |
566 *sdu_data16 = *cci_data->fbs.data16_reg; | |
567 | |
568 sdu_data16++; | |
569 } | |
570 | |
571 sdu_data8 = (UBYTE*)sdu_data16; | |
572 | |
573 if (frame8 != 0) | |
574 { | |
575 | |
576 #ifdef _GEA_SIMULATION_ | |
577 ciph_reg8_read_sim(); | |
578 #endif | |
579 | |
580 *sdu_data8 = *cci_data->fbs.data8_reg; | |
581 | |
582 sdu_data8++; | |
583 } | |
584 | |
585 #if (BOARD == 61 OR BOARD == 71) /* G-Sample or I-Sample */ | |
586 *cci_data->fbs.switch_reg = 0; | |
587 #endif | |
588 | |
589 /* | |
590 * Copy FCS to destination sdu, taking byte ordering of FCS registers | |
591 * into account, e.g.: | |
592 * reg1 reg2 sdu | |
593 * 29 FC xx 36 -> FC 29 36 | |
594 */ | |
595 *sdu_data8 = (UBYTE) (*cci_data->fbs.fcs_ul_reg1 & 0x00FF); | |
596 sdu_data8++; | |
597 *sdu_data8 = (UBYTE)((*cci_data->fbs.fcs_ul_reg1 & 0xFF00) >> 8); | |
598 sdu_data8++; | |
599 *sdu_data8 = (UBYTE) (*cci_data->fbs.fcs_ul_reg2 & 0x00FF); | |
600 | |
601 } /* ciph_get_ciphered_data() */ | |
602 | |
603 /* | |
604 +------------------------------------------------------------------------------ | |
605 | Function : ciph_get_deciphered_data | |
606 +------------------------------------------------------------------------------ | |
607 | Description : The function ciph_get_deciphered_data() .... | |
608 | | |
609 | Parameters : T_CCI_DECIPHER_CNF *decipher_cnf | |
610 | | |
611 +------------------------------------------------------------------------------ | |
612 */ | |
613 LOCAL void ciph_get_deciphered_data (T_CIPH_out_data *out_data, U8 *status) | |
614 { | |
615 int i, | |
616 frame8, | |
617 frame16; | |
618 USHORT *sdu_data16; | |
619 UBYTE *sdu_data8; | |
620 | |
621 | |
622 TRACE_FUNCTION( "ciph_get_deciphered_data" ); | |
623 | |
624 i = out_data->len; | |
625 | |
626 frame16 = i / 2; | |
627 frame8 = i % 2; | |
628 | |
629 #ifdef _GEA_SIMULATION_ | |
630 cci_data->fbs.simulated_reg = cci_data->fbs.simulated_reg_buffer; | |
631 #endif | |
632 | |
633 sdu_data16 = (USHORT*)out_data->buf; | |
634 | |
635 #if (BOARD == 61 OR BOARD == 71) /* G-Sample or I-Sample */ | |
636 *cci_data->fbs.switch_reg = 1; | |
637 #endif | |
638 | |
639 for (i=0; i<frame16; i++) | |
640 { | |
641 | |
642 #ifdef _GEA_SIMULATION_ | |
643 ciph_reg16_read_sim(); | |
644 #endif | |
645 | |
646 *sdu_data16 = *cci_data->fbs.data16_reg; | |
647 | |
648 sdu_data16++; | |
649 } | |
650 | |
651 sdu_data8 = (UBYTE*)sdu_data16; | |
652 | |
653 if (frame8 != 0) | |
654 { | |
655 | |
656 #ifdef _GEA_SIMULATION_ | |
657 ciph_reg8_read_sim(); | |
658 #endif | |
659 | |
660 *sdu_data8 = *cci_data->fbs.data8_reg; | |
661 | |
662 sdu_data8++; | |
663 } | |
664 | |
665 #if (BOARD == 61 OR BOARD == 71) /* G-Sample or I-Sample */ | |
666 *cci_data->fbs.switch_reg = 0; | |
667 #endif | |
668 | |
669 /* | |
670 * Get result from FCS calculation | |
671 */ | |
672 *status = ciph_fcs_check(sdu_data8); | |
673 | |
674 } /* ciph_get_deciphered_data() */ | |
675 | |
676 | |
677 | |
678 /* | |
679 +------------------------------------------------------------------------------ | |
680 | Function : ciph_fill_ul_reg | |
681 +------------------------------------------------------------------------------ | |
682 | Description : The function ciph_fill_ul_reg() fills the uplink registers. | |
683 | | |
684 | Parameters : | |
685 +------------------------------------------------------------------------------ | |
686 */ | |
687 LOCAL void ciph_fill_ul_reg ( T_CIPH_cipher_req_parms *cipher_req_parms, | |
688 T_CIPH_in_data_list *in_data_list ) | |
689 { | |
690 int i, j; | |
691 int frame8; | |
692 UBYTE *desc_data8; | |
693 U16 len = 0; | |
694 | |
695 TRACE_FUNCTION( "ciph_fill_ul_reg" ); | |
696 | |
697 /* | |
698 * setting the protected mode variable | |
699 */ | |
700 if (cipher_req_parms->gprs_parameters.pm EQ CIPH_PM_PROTECTED) | |
701 { | |
702 *cci_data->fbs.conf_ul_reg1 |= PROTECTED; | |
703 } | |
704 else | |
705 { | |
706 *cci_data->fbs.conf_ul_reg1 &= NON_PROTECTED; | |
707 } | |
708 | |
709 /* | |
710 * FCS is always calculated | |
711 */ | |
712 *cci_data->fbs.conf_ul_reg1 |= FCS_COMPUTED; | |
713 | |
714 /* | |
715 * direction is uplink | |
716 */ | |
717 /* Direction muss noch in init function gesetzt werden */ | |
718 *cci_data->fbs.conf_ul_reg1 &= D_UL; | |
719 | |
720 if (cci_data->fbs.ciph_params.algo NEQ CIPH_EA0) | |
721 { | |
722 *cci_data->fbs.conf_ul_reg1 |= ENCRYPT; | |
723 | |
724 if(cci_data->fbs.ciph_params.algo EQ CIPH_EA1) | |
725 { | |
726 *cci_data->fbs.conf_ul_reg1 &= GEA_FIRST; | |
727 } | |
728 else | |
729 if(cci_data->fbs.ciph_params.algo EQ CIPH_EA2) | |
730 { | |
731 *cci_data->fbs.conf_ul_reg1 |= GEA_SECOND; | |
732 } | |
733 else | |
734 { | |
735 TRACE_ERROR ("Illegal ciphering_algorithm"); | |
736 } | |
737 | |
738 /* | |
739 * if the condition is CCI_CIPHER_NO_ALGORITHM we don't use subsequent statements | |
740 */ | |
741 *cci_data->fbs.kc_reg1 = (USHORT)((USHORT)(cci_data->fbs.ciph_params.ptr_ck->ck_element[1]) << 8)+ | |
742 (USHORT)(cci_data->fbs.ciph_params.ptr_ck->ck_element[0]); | |
743 *cci_data->fbs.kc_reg2 = (USHORT)((USHORT)(cci_data->fbs.ciph_params.ptr_ck->ck_element[3]) << 8)+ | |
744 (USHORT)(cci_data->fbs.ciph_params.ptr_ck->ck_element[2]); | |
745 *cci_data->fbs.kc_reg3 = (USHORT)((USHORT)(cci_data->fbs.ciph_params.ptr_ck->ck_element[5]) << 8)+ | |
746 (USHORT)(cci_data->fbs.ciph_params.ptr_ck->ck_element[4]); | |
747 *cci_data->fbs.kc_reg4 = (USHORT)((USHORT)(cci_data->fbs.ciph_params.ptr_ck->ck_element[7]) << 8)+ | |
748 (USHORT)(cci_data->fbs.ciph_params.ptr_ck->ck_element[6]); | |
749 | |
750 /* store ciphering key in the local buffer for later verification */ | |
751 if(cci_data->fbs.cci_info_trace){ | |
752 tmp_key[0] = *cci_data->fbs.kc_reg1; | |
753 tmp_key[1] = *cci_data->fbs.kc_reg2; | |
754 tmp_key[2] = *cci_data->fbs.kc_reg3; | |
755 tmp_key[3] = *cci_data->fbs.kc_reg4; | |
756 } | |
757 | |
758 /* | |
759 * FRAME DEPENDENT CIPHERING INPUT entity is ULONG in the primitive | |
760 */ | |
761 *cci_data->fbs.conf_ul_reg4 = (USHORT)(cipher_req_parms->gprs_parameters.ciphering_input); | |
762 *cci_data->fbs.conf_ul_reg5 = (USHORT)(cipher_req_parms->gprs_parameters.ciphering_input >> 16); | |
763 | |
764 /* | |
765 * it is assumed that MSB is first 16 bit and LSB part is last 16 bits | |
766 */ | |
767 } | |
768 else | |
769 { | |
770 /* | |
771 * in this case we don't fill the registers that contain ciphering keys | |
772 */ | |
773 *cci_data->fbs.conf_ul_reg1 &= NO_ENCRYPT; | |
774 } | |
775 | |
776 /* | |
777 * Enter LLC-PDU size in bytes | |
778 */ | |
779 for (i = 0; i < in_data_list->c_in_data; i++) { | |
780 len += in_data_list->ptr_in_data[i].len; | |
781 } | |
782 *cci_data->fbs.conf_ul_reg2 = (USHORT)len; | |
783 /* | |
784 * conf_ul_reg3 is seperated into 2 parts of UBYTE: | |
785 * -> lowbyte = N202 | |
786 * -> hightbyte = LLC-PDU header size in bytes (indicate the offset of information) | |
787 */ | |
788 *cci_data->fbs.conf_ul_reg3 = (USHORT)((cipher_req_parms->gprs_parameters.header_size << 8) | CIPH_N202); | |
789 | |
790 #ifdef _GEA_SIMULATION_ | |
791 cci_data->fbs.simulated_reg = cci_data->fbs.simulated_reg_buffer; | |
792 #endif | |
793 | |
794 *cci_data->fbs.conf_ul_reg1 &= NO_INPUT_SHIFT; | |
795 | |
796 #if (BOARD == 61 OR BOARD == 71) /* G-Sample or I-Sample */ | |
797 *cci_data->fbs.switch_reg = 1; | |
798 | |
799 #ifdef LLC_TRACE_GEA_PARAM | |
800 cci_trace_gea_param(); | |
801 #endif | |
802 | |
803 #endif | |
804 | |
805 for (i = 0; i < in_data_list->c_in_data; i++) { | |
806 desc_data8 = (U8*)in_data_list->ptr_in_data[i].buf; | |
807 frame8 = in_data_list->ptr_in_data[i].len; | |
808 for (j=0; j < frame8; j++) | |
809 { | |
810 *cci_data->fbs.data8_reg = *desc_data8; | |
811 | |
812 #ifdef _GEA_SIMULATION_ | |
813 ciph_reg8_write_sim(); | |
814 #endif | |
815 desc_data8++; | |
816 } | |
817 } | |
818 | |
819 #if (BOARD == 61 OR BOARD == 71) /* G-Sample or I-Sample */ | |
820 *cci_data->fbs.switch_reg = 0; | |
821 #endif | |
822 } /* ciph_fill_ul_reg() */ | |
823 | |
824 | |
825 | |
826 /* | |
827 +------------------------------------------------------------------------------ | |
828 | Function : ciph_fill_dl_reg | |
829 +------------------------------------------------------------------------------ | |
830 | Description : The function ciph_fill_dl_reg() | |
831 | | |
832 | Parameters : | |
833 | | |
834 +------------------------------------------------------------------------------ | |
835 */ | |
836 LOCAL void ciph_fill_dl_reg (T_CIPH_cipher_req_parms *cipher_req_parms, | |
837 T_CIPH_in_data_list *in_data_list ) | |
838 { | |
839 ULONG i, j; | |
840 ULONG frame8; | |
841 UBYTE *desc_data8; | |
842 ULONG len = 0; | |
843 | |
844 TRACE_FUNCTION( "ciph_fill_dl_reg" ); | |
845 | |
846 /* | |
847 * setting the protected mode variable | |
848 */ | |
849 if(cipher_req_parms->gprs_parameters.pm EQ CIPH_PM_PROTECTED) | |
850 { | |
851 *cci_data->fbs.conf_dl_reg1 |= PROTECTED; | |
852 } | |
853 else | |
854 { | |
855 *cci_data->fbs.conf_dl_reg1 &= NON_PROTECTED; | |
856 } | |
857 | |
858 /* | |
859 * FCS is always calculated | |
860 */ | |
861 *cci_data->fbs.conf_dl_reg1 |= FCS_COMPUTED; | |
862 | |
863 /* | |
864 * data always copied aligned independent | |
865 */ | |
866 *cci_data->fbs.conf_dl_reg1 &= NO_INPUT_SHIFT; | |
867 | |
868 /* | |
869 * direction is downlink | |
870 */ | |
871 *cci_data->fbs.conf_dl_reg1 |= D_DL; | |
872 | |
873 if(cci_data->fbs.ciph_params.algo NEQ CIPH_EA0) | |
874 { | |
875 *cci_data->fbs.conf_dl_reg1 |= ENCRYPT; | |
876 | |
877 if(cci_data->fbs.ciph_params.algo EQ CIPH_EA1) | |
878 { | |
879 *cci_data->fbs.conf_dl_reg1 &= GEA_FIRST; | |
880 } | |
881 else | |
882 if(cci_data->fbs.ciph_params.algo EQ CIPH_EA2) | |
883 { | |
884 *cci_data->fbs.conf_dl_reg1 |= GEA_SECOND; | |
885 } | |
886 else | |
887 { | |
888 TRACE_ERROR ("Illegal ciphering_algorithm"); | |
889 } | |
890 | |
891 *cci_data->fbs.kc_reg1 = | |
892 (USHORT)((USHORT)(cci_data->fbs.ciph_params.ptr_ck->ck_element[1]) << 8) + | |
893 (USHORT)(cci_data->fbs.ciph_params.ptr_ck->ck_element[0]); | |
894 | |
895 *cci_data->fbs.kc_reg2 = | |
896 (USHORT)((USHORT)(cci_data->fbs.ciph_params.ptr_ck->ck_element[3]) << 8) + | |
897 (USHORT)(cci_data->fbs.ciph_params.ptr_ck->ck_element[2]); | |
898 | |
899 *cci_data->fbs.kc_reg3 = | |
900 (USHORT)((USHORT)(cci_data->fbs.ciph_params.ptr_ck->ck_element[5]) << 8) + | |
901 (USHORT)(cci_data->fbs.ciph_params.ptr_ck->ck_element[4]); | |
902 | |
903 *cci_data->fbs.kc_reg4 = | |
904 (USHORT)((USHORT)(cci_data->fbs.ciph_params.ptr_ck->ck_element[7]) << 8) + | |
905 (USHORT)(cci_data->fbs.ciph_params.ptr_ck->ck_element[6]); | |
906 | |
907 /* store ciphering key in local buffer for later verification */ | |
908 if(cci_data->fbs.cci_info_trace){ | |
909 tmp_key[0] = *cci_data->fbs.kc_reg1; | |
910 tmp_key[1] = *cci_data->fbs.kc_reg2; | |
911 tmp_key[2] = *cci_data->fbs.kc_reg3; | |
912 tmp_key[3] = *cci_data->fbs.kc_reg4; | |
913 } | |
914 | |
915 /* | |
916 * FRAME DEPENDENT CIPHERING INPUT entity is ULONG in the primitive | |
917 */ | |
918 *cci_data->fbs.conf_dl_reg4 = (USHORT)(cipher_req_parms->gprs_parameters.ciphering_input); | |
919 *cci_data->fbs.conf_dl_reg5 = (USHORT)(cipher_req_parms->gprs_parameters.ciphering_input >> 16); | |
920 } | |
921 else | |
922 { | |
923 /* | |
924 * in this case we don't fill the registers that contain ciphering keys | |
925 */ | |
926 *cci_data->fbs.conf_dl_reg1 &= NO_ENCRYPT; | |
927 } | |
928 | |
929 /* | |
930 * Write length of LLC-PDU in bytes including FCS | |
931 */ | |
932 for (i = 0; i < in_data_list->c_in_data; i++) { | |
933 len += in_data_list->ptr_in_data[i].len; | |
934 } | |
935 | |
936 *cci_data->fbs.conf_dl_reg2 = (USHORT)len; | |
937 | |
938 /* | |
939 * conf_dl_reg3 is seperated into 2 parts of UBYTE: | |
940 * -> lowbyte = N202 | |
941 * -> hightbyte = LLC-PDU header size in bytes (indicate the offset of information) | |
942 */ | |
943 *cci_data->fbs.conf_dl_reg3 = (USHORT)((cipher_req_parms->gprs_parameters.header_size << 8) | CIPH_N202); | |
944 | |
945 | |
946 #ifdef _GEA_SIMULATION_ | |
947 cci_data->fbs.simulated_reg = cci_data->fbs.simulated_reg_buffer; | |
948 #endif | |
949 | |
950 #if (BOARD == 61 OR BOARD == 71) /* G-Sample or I-Sample */ | |
951 *cci_data->fbs.switch_reg = 1; | |
952 #endif | |
953 | |
954 for (i = 0; i < in_data_list->c_in_data; i++) { | |
955 desc_data8 = (UBYTE*)in_data_list->ptr_in_data[i].buf; | |
956 frame8 = in_data_list->ptr_in_data[i].len; | |
957 | |
958 for (j=0; j < frame8; j++){ | |
959 *cci_data->fbs.data8_reg = desc_data8[j]; | |
960 #ifdef _GEA_SIMULATION_ | |
961 ciph_reg8_write_sim(); | |
962 #endif | |
963 } | |
964 } | |
965 | |
966 #if (BOARD == 61 OR BOARD == 71) /* G-Sample or I-Sample */ | |
967 *cci_data->fbs.switch_reg = 0; | |
968 #endif | |
969 | |
970 } /* ciph_fill_dl_reg() */ | |
971 | |
972 #if (BOARD == 61 OR BOARD == 71) /* G-Sample or I-Sample */ | |
973 | |
974 #ifdef LLC_TRACE_GEA_PARAM | |
975 LOCAL void cci_trace_gea_param( void ) | |
976 { | |
977 TRACE_EVENT_P9( "cci_trace_gea_param_1 %04X %04X %04X %04X %04X %04X %04X %04X %04X", | |
978 *cci_data->fbs.cntl_reg , | |
979 *cci_data->fbs.status_reg , | |
980 *cci_data->fbs.status_irq_reg, | |
981 *cci_data->fbs.conf_ul_reg1 , | |
982 *cci_data->fbs.conf_ul_reg2 , | |
983 *cci_data->fbs.conf_ul_reg3 , | |
984 *cci_data->fbs.conf_ul_reg4 , | |
985 *cci_data->fbs.conf_ul_reg5 , | |
986 *cci_data->fbs.conf_dl_reg1 ); | |
987 | |
988 TRACE_EVENT_P9( "cci_trace_gea_param_2 %04X %04X %04X %04X %04X %04X %04X %04X %04X", | |
989 *cci_data->fbs.conf_dl_reg2 , | |
990 *cci_data->fbs.conf_dl_reg3 , | |
991 *cci_data->fbs.conf_dl_reg4 , | |
992 *cci_data->fbs.conf_dl_reg5 , | |
993 *cci_data->fbs.fcs_ul_reg1 , | |
994 *cci_data->fbs.fcs_ul_reg2 , | |
995 *cci_data->fbs.fcs_dl_reg1 , | |
996 *cci_data->fbs.fcs_dl_reg2 , | |
997 *cci_data->fbs.switch_reg ); | |
998 } | |
999 #endif | |
1000 #endif | |
1001 #endif /* TI_PS_OP_CIPH_DRIVER */ |