1 /******************************************************************************
2 * FILE PURPOSE: Main Routines for SA LLD
3 ******************************************************************************
4 * FILE NAME: salld.c
5 *
6 * DESCRIPTION: Main SA LLD functions
7 *
8 * FUNCTION DESCRIPTION
9 * ======== ===========
10 * salldGetSizes() Obtains memory requirements for an instance of SALLD
11 * Sa_chanInit() Creates an instance of SALLD
12 *
13 *
14 *
15 * REVISION HISTORY:
16 *
17 *
18 * (C) Copyright 2009-2013, Texas Instruments Inc.
19 *
20 * Redistribution and use in source and binary forms, with or without
21 * modification, are permitted provided that the following conditions
22 * are met:
23 *
24 * Redistributions of source code must retain the above copyright
25 * notice, this list of conditions and the following disclaimer.
26 *
27 * Redistributions in binary form must reproduce the above copyright
28 * notice, this list of conditions and the following disclaimer in the
29 * documentation and/or other materials provided with the
30 * distribution.
31 *
32 * Neither the name of Texas Instruments Incorporated nor the names of
33 * its contributors may be used to endorse or promote products derived
34 * from this software without specific prior written permission.
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
37 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
38 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
39 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
40 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
43 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
45 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
46 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47 *
48 */
49 /* System level header files */
51 #include <stdlib.h>
52 #include <string.h>
54 /* SALLD header files */
55 #include <ti/drv/sa/salld.h>
56 #include <ti/drv/sa/sa_osal.h>
57 #include <ti/drv/sa/src/salldloc.h>
58 #include <ti/drv/sa/src/salldproto.h>
60 /* SALLD Protocol Specific API files */
61 #include <ti/drv/sa/src/proto/srtp/salldsrtp.h>
62 #include <ti/drv/sa/src/proto/srtp/salldsrtcp.h>
63 #include <ti/drv/sa/src/proto/ipsec/salldipsec.h>
64 #include <ti/drv/sa/src/proto/airciph/salldac.h>
65 #include <ti/drv/sa/src/proto/datamode/sallddm.h>
67 /* SALLD protocol call table */
68 const Sa_ProtocolCallTbl_t* salld_callTblPtr[] =
69 {
70 #if !defined(NSS_LITE) && !defined(NSS_LITE2)
71 &Sa_callTblStrp,
72 &Sa_callTblSrtcp,
73 &Sa_callTblIpsecAh,
74 &Sa_callTblIpsecEsp,
75 &Sa_callTblAc,
76 #endif
77 &Sa_callTblDataMode,
78 NULL
79 };
81 /* SA Local object */
82 salldLocObj_t salldLObj;
84 /******************************************************************************
85 * FUNCTION PURPOSE: Return the Protocol-specific Channel instance size
86 ******************************************************************************
87 * DESCRIPTION: This function returns the Protocol-specific Channel instance size
88 *****************************************************************************/
89 static void salld_get_chan_inst_size(Sa_SecProto_e protocolType, int* pSize)
90 {
92 /* Get sizes based on the security protocol */
93 switch (protocolType)
94 {
95 case sa_PT_NULL:
96 *pSize = salld_data_mode_get_size();
97 break;
98 #if !defined(NSS_LITE) && !defined(NSS_LITE2)
99 case sa_PT_SRTP:
100 *pSize = salld_srtp_get_size();
101 break;
102 case sa_PT_SRTCP:
103 *pSize = salld_srtcp_get_size();
104 break;
105 case sa_PT_IPSEC_AH:
106 case sa_PT_IPSEC_ESP:
107 *pSize = salld_ipsec_get_size();
108 break;
109 case sa_PT_3GPP_AC:
110 *pSize = salld_ac_get_size();
111 break;
112 #endif
113 default:
114 *pSize = 0;
115 }
116 }
119 #if !defined(NSS_LITE) && !defined(NSS_LITE2)
120 /******************************************************************************
121 * FUNCTION PURPOSE: Select IPSEC engine
122 ******************************************************************************
123 * DESCRIPTION: This function returns the index of selected IPSEC engine
124 * based on system and channel configuration.
125 *
126 *****************************************************************************/
127 static uint16_t salld_select_ipsec_engine(salldObj_t *inst, uint16_t sel)
128 {
129 int engSelMode = SALLD_GET_STATE_ENG_SEL_MODE(inst);
131 switch (engSelMode)
132 {
133 case sa_EngSelMode_LOADBALANCED:
134 {
135 if (inst->engCounter[0] > inst->engCounter[1])
136 {
137 inst->engCounter[1]++;
138 return(1);
139 }
140 else
141 {
142 inst->engCounter[0]++;
143 return(0);
144 }
145 }
147 case sa_EngSelMode_ROUNDROBIN:
148 {
149 if (inst->engCounter[0] == 0)
150 {
151 inst->engCounter[0] = 1;
152 return(0);
153 }
154 else
155 {
156 inst->engCounter[0] = 0;
157 return(1);
158 }
159 }
161 case sa_EngSelMode_USERSPECIFIED:
162 {
163 /* sa_EngSelMode_USERSPECIFIED */
164 return((sel == 0)?0:1);
165 }
167 default:
168 return(0);
169 }
171 }
173 #endif
175 /******************************************************************************
176 * FUNCTION PURPOSE: Obtains memory buffer requirements for an SALLD
177 * channel instance
178 ******************************************************************************
179 * DESCRIPTION: This function obtains memory buffer requirements for an SALLD
180 * channel instance. The memory buffer requirements are in terms of
181 * the size and alignment array which must not be changed by external
182 * software.
183 * Worst case memory size requirements are computed using parameters
184 * provided by Sa_ChanSizeCfg_t.
185 *
186 * int16_t Sa_chanGetBufferReq (
187 * Sa_ChanSizeCfg_t *sizeCfg, - Configuration information to be used in
188 * estimating the worst case buffer sizes
189 * int sizes[], - Array of size requirements
190 * int aligns[]) - Array of alignment requirements
191 *
192 * 1. Get sizes for all the security profiles in the build.
193 * 2. Find the maximum of all the sizes.
194 * 3. Assumptions:
195 * --All the memory is from heap.
196 * --There is no special requirement for memory.
197 *
198 * Return values: sa_ERR_OK
199 * sa_ERR_GEN
200 * sa_ERR_PARAMS
201 *
202 *
203 *****************************************************************************/
204 int16_t Sa_chanGetBufferReq (Sa_ChanSizeCfg_t *cfg, int sizes[], int aligns[])
205 {
207 int size;
208 int alignment;
210 if(cfg == NULL)
211 return(sa_ERR_PARAMS);
213 alignment = max(8, cfg->cacheLineSize);
215 /* Get sizes based on the security protocol */
216 salld_get_chan_inst_size(cfg->protocolType, &size);
218 if(size == 0)
219 return(sa_ERR_PARAMS);
221 sizes[0] = SALLD_ROUND_UP(size, alignment);
223 if (cfg->ctrlBitMap & sa_SIZE_CONFIG_CREATE_SHADOW_INST)
224 {
225 sizes[0] *= 2; /* Double the instance size to include the shadow instance */
226 }
228 aligns[0] = alignment;
230 return(sa_ERR_OK);
231 } /* Sa_chanGetBufferReq */
234 /******************************************************************************
235 * FUNCTION PURPOSE: Create and initialize an SALLD channel instance
236 ******************************************************************************
237 * DESCRIPTION: This function initialize an instance of SALLD channel and its
238 * corresponding instance structure based on channel configuration data
239 * such as the security protocol and etc.
240 *
241 * int16_t Sa_chanCreate (
242 * Sa_Handle handle, - SALLD instance identifier.
243 * Sa_ChanConfig_t *cfg - Pointer to configuration structure
244 * void* bases[] - Array of the memory buffer base addresses
245 * Sa_ChanHandle *pChanHdl) - Store the channel instance pointer
246 *
247 * Return values: sa_ERR_OK
248 * sa_ERR_GEN
249 * sa_ERR_PARAMS
250 * sa_ERR_NOMEM
251 * sa_ERR_INV_BUF
252 * sa_ERR_INV_PROTO_TYPE
253 *
254 *****************************************************************************/
255 int16_t Sa_chanCreate (Sa_Handle handle, Sa_ChanConfig_t *cfg, void* bases[],
256 Sa_ChanHandle *pChanHdl)
257 {
258 Sa_ProtocolCallTbl_t **CallTable;
259 salldObj_t *sysInst = (salldObj_t *)sa_CONV_OFFSET_TO_ADDR(salldLObj.instPoolBaseAddr, handle);
260 salldInst_t *inst = (salldInst_t *)bases[SALLD_CHAN_BUFN];
261 int i, instSize, alignment;
262 salldInst_t *shadowInst = NULL;
263 int16_t retCode;
265 /* Test instance pointer */
266 if (sysInst == NULL || cfg == NULL || pChanHdl == NULL)
267 return(sa_ERR_PARAMS);
269 if (sysInst->magic != SALLD_INST_MAGIC_WORD)
270 {
271 if(sysInst->magic == salld_swiz32(SALLD_INST_MAGIC_WORD))
272 return(sa_ERR_INV_ENDIAN_MODE);
273 else
274 return(sa_ERR_INV_HANDLE);
275 }
276 /* Get sizes based on the security protocol */
277 salld_get_chan_inst_size(cfg->sizeConfig.protocolType, &instSize);
278 alignment = max(4, cfg->sizeConfig.cacheLineSize);
279 instSize = SALLD_ROUND_UP(instSize, alignment);
280 if (cfg->sizeConfig.cacheLineSize)
281 {
282 /* Invalidate the Cache Contents */
283 Sa_osalBeginMemAccess(inst, instSize);
284 }
286 memset(inst, 0, instSize);
288 /* Allocate all dynamic buffers (base address != NULL ?) */
289 for (i = 0; i < SALLD_CHAN_NBUF; i++) {
290 if (bases[i] == NULL) {
291 return (sa_ERR_NOMEM);
292 }
293 inst->memBaseOffsets[i] = (uint32_t) sa_CONV_ADDR_TO_OFFSET(salldLObj.instPoolBaseAddr, bases[i]);
294 }
296 if (cfg->sizeConfig.ctrlBitMap & sa_SIZE_CONFIG_CREATE_SHADOW_INST)
297 {
298 /* Shadow instance is created just after system instance in the memory
299 hence the shadowoffset = system offset + size of system structure */
300 inst->shadowInstOffset = (uint32_t) inst->memBaseOffsets[SALLD_CHAN_BUFN] + instSize;
301 shadowInst = (salldInst_t *)(sa_CONV_OFFSET_TO_ADDR(salldLObj.instPoolBaseAddr, inst->shadowInstOffset));
303 if (cfg->sizeConfig.cacheLineSize)
304 {
305 /* Invalidate the Cache Contents */
306 Sa_osalBeginMemAccess(shadowInst, instSize);
307 }
308 }
310 /* modify the Security Profile to one of the ones in the call table */
311 for (i =0, CallTable = (Sa_ProtocolCallTbl_t **)&salld_callTblPtr[0]; *CallTable != NULL; CallTable++, i++)
312 {
313 if ((*CallTable)->secProtocolType == cfg->sizeConfig.protocolType)
314 {
315 inst->protoTblIndex = i;
316 break;
317 }
318 }
320 /* return an error if the profile type is not supported */
321 if (*CallTable == NULL)
322 return (sa_ERR_INV_PROTO_TYPE);
324 /* Default Instance Initialization */
325 inst->magic = SALLD_INST_MAGIC_WORD;
326 inst->ID = cfg->ID;
327 inst->stateBitfield = 0; /* set SALLD state to CLOSED */
328 inst->instSize = instSize;
329 inst->ownerInstOffset = sysInst->memBaseOffsets[SALLD_BUFN];
330 SALLD_SET_STATE_SHARED(inst, (cfg->sizeConfig.cacheLineSize > 0));
332 *pChanHdl = (Sa_ChanHandle)sa_CONV_ADDR_TO_OFFSET(salldLObj.instPoolBaseAddr, inst);
334 #if !defined(NSS_LITE) && !defined(NSS_LITE2)
336 /* Read the engine select information from salldHandle */
337 if ((cfg->sizeConfig.protocolType == sa_PT_IPSEC_AH) || (cfg->sizeConfig.protocolType == sa_PT_IPSEC_ESP))
338 {
339 uint32_t mtCsKey;
340 /* CRITICAL Section Start: The global instance is a shared resource which needs to be
341 * protected from the following:
342 * a) Multiple Cores acccess
343 */
344 Sa_osalMtCsEnter(&mtCsKey);
346 /* Invalidate the Cache Contents */
347 Sa_osalBeginMemAccess(sysInst, sizeof(salldObj_t));
349 inst->engSelect = salld_select_ipsec_engine(sysInst, cfg->engSelect);
351 /* Writeback the instance updates */
352 Sa_osalEndMemAccess(sysInst, sizeof(salldObj_t));
354 /* Critical Section End */
355 Sa_osalMtCsExit(mtCsKey);
357 }
358 else
359 {
360 inst->engSelect = SALLD_ENG_SELECT_NA;
361 }
363 #endif
365 /* Populate the shadow Instance which will be used at another processer with different Endian mode if required */
366 if (shadowInst)
367 {
368 salldObj_t *sysShadowInst = (salldObj_t *)(sa_CONV_OFFSET_TO_ADDR(salldLObj.instPoolBaseAddr, sysInst->shadowInstOffset));
370 if (!sysShadowInst)
371 {
372 return(sa_ERR_INV_HANDLE);
373 }
375 memset(shadowInst, 0, instSize);
376 shadowInst->magic = salld_swiz32(SALLD_INST_MAGIC_WORD);
377 shadowInst->ID = SALLD_SWIZ(inst->ID);
378 shadowInst->stateBitfield = SALLD_SWIZ(inst->stateBitfield);
379 shadowInst->instSize = SALLD_SWIZ(inst->instSize);
380 shadowInst->shadowInstOffset = SALLD_SWIZ(inst->shadowInstOffset);
381 shadowInst->protoTblIndex = SALLD_SWIZ(inst->protoTblIndex);
382 shadowInst->updateCnt = SALLD_SWIZ(inst->updateCnt);
383 shadowInst->engSelect = SALLD_SWIZ(inst->engSelect);
384 shadowInst->ownerInstOffset = SALLD_SWIZ(sysInst->shadowInstOffset);
386 /* Note: the memory buffers can not be used by the shadow processors since the memory free can only occur at the master core */
387 }
389 /* call the initialization function for the actual security profile type */
390 retCode = (*salld_callTblPtr[inst->protoTblIndex]->chanInit) (inst, (void *)cfg);
392 /* write back the channel specific instance */
393 if (SALLD_TEST_STATE_SHARED(inst))
394 {
395 Sa_osalEndMemAccess(inst, inst->instSize);
397 if (shadowInst)
398 {
399 Sa_osalEndMemAccess(shadowInst, inst->instSize);
400 }
401 }
403 return(retCode);
405 } /* Sa_chanCreate */
408 /******************************************************************************
409 * FUNCTION PURPOSE: Start an SALLD channel instance
410 ******************************************************************************
411 * DESCRIPTION: This function starts an instance of SALLD channel at local
412 * core. It is assumed that this channel has been created and configured
413 * at another core.
414 *
415 * int16_t Sa_chanStart (
416 * Sa_ChanHandle handle) - SALLD channel identifier
417 *
418 * Return values: sa_ERR_OK
419 * sa_ERR_PARAMS
420 *
421 * Note: This function should be called prior to other channel APIs
422 * such as Sa_chanSendData() and Sa_chanReceiveData() are invoked
423 *****************************************************************************/
424 int16_t Sa_chanStart (Sa_Handle handle)
425 {
426 salldInst_t *inst = (salldInst_t *) (sa_CONV_OFFSET_TO_ADDR(salldLObj.instPoolBaseAddr, handle));
428 /* Invalidate the Cache Contents */
429 Sa_osalBeginMemAccess(inst, sizeof(salldInst_t));
431 if (inst->magic != SALLD_INST_MAGIC_WORD)
432 {
433 if(inst->magic == salld_swiz32(SALLD_INST_MAGIC_WORD))
434 return(sa_ERR_INV_ENDIAN_MODE);
435 else
436 return(sa_ERR_INV_HANDLE);
437 }
439 /* Invalidate the protocol-specific channel instance */
440 if(SALLD_TEST_STATE_SHARED(inst))
441 Sa_osalBeginMemAccess(inst, inst->instSize);
443 return (sa_ERR_OK);
445 }
448 /******************************************************************************
449 * FUNCTION PURPOSE: Obtain the SA channelID
450 ******************************************************************************
451 * DESCRIPTION: This function returns the SA channel ID associated with the
452 * specified handle.
453 *
454 *****************************************************************************/
455 uint32_t Sa_chanGetID (Sa_ChanHandle handle)
456 {
457 salldInst_t *inst = (salldInst_t *)(sa_CONV_OFFSET_TO_ADDR(salldLObj.instPoolBaseAddr, handle));
459 if ((inst == NULL) || (inst->magic != SALLD_INST_MAGIC_WORD))
460 {
461 return(0);
462 }
464 return (inst->ID);
465 }
467 /******************************************************************************
468 * FUNCTION PURPOSE: SALLD Channel Control function
469 ******************************************************************************
470 * DESCRIPTION: This function controls the operations of a channel instance of
471 * SALLD. It is used to configure and/or re-configure the SALLD channel
472 * with various control information. This function should be called
473 * multiple times to configure and activate the SALLD channel during
474 * call setup period. Then it is typically called to perform re-key opeartion
475 * subsequently
476 *
477 * int16_t Sa_chanControl (
478 * Sa_ChanHandle handle - SALLD channel identifier
479 * Sa_ChanCtrlInfo_t *ctrl) - a pointer to control structure
480 *
481 * Return values: sa_ERR_OK
482 * sa_ERR_GEN
483 * sa_ERR_PARAMS
484 * sa_ERR_INV_PROTO_TYPE
485 *
486 *****************************************************************************/
487 int16_t Sa_chanControl (Sa_ChanHandle handle, Sa_ChanCtrlInfo_t *ctrl)
488 {
489 int16_t ret = sa_ERR_GEN;
490 salldInst_t *inst = (salldInst_t *)(sa_CONV_OFFSET_TO_ADDR(salldLObj.instPoolBaseAddr, handle));
491 salldInst_t* shadowInst = NULL;
493 /* Invalidate the protocol-specific channel instance */
494 if (SALLD_TEST_STATE_SHARED(inst))
495 {
496 Sa_osalBeginMemAccess(inst, inst->instSize);
498 /* non zero shadow instance offset indicates the presense of shadow instance */
499 if(inst->shadowInstOffset)
500 {
501 shadowInst = (salldInst_t *)(sa_CONV_OFFSET_TO_ADDR(salldLObj.instPoolBaseAddr, inst->shadowInstOffset));
502 Sa_osalBeginMemAccess(shadowInst, inst->instSize);
503 }
504 }
506 if (inst->magic != SALLD_INST_MAGIC_WORD)
507 {
508 if(inst->magic == salld_swiz32(SALLD_INST_MAGIC_WORD))
509 return (sa_ERR_INV_ENDIAN_MODE);
510 else
511 return (sa_ERR_INV_HANDLE);
512 }
514 if((ctrl->ctrlType == sa_CHAN_CTRL_GEN_CONFIG)
515 && (ctrl->ctrlInfo.gen.validBitfield & sa_CONTROLINFO_VALID_CTRL_BITMAP))
516 {
517 inst->stateBitfield &= ~sa_CONTROLINFO_CTRL_OP_MASK;
518 inst->stateBitfield |= (ctrl->ctrlInfo.gen.ctrlBitfield & sa_CONTROLINFO_CTRL_OP_MASK);
519 }
521 /* Calls the appropriate salldXyzControl function */
522 ret = (*salld_callTblPtr[inst->protoTblIndex]->chanControl)(inst, (void *)ctrl);
524 /* write back the channel specific instance */
525 if (SALLD_TEST_STATE_SHARED(inst))
526 {
527 Sa_osalEndMemAccess(inst, inst->instSize);
529 if(inst->shadowInstOffset)
530 Sa_osalEndMemAccess(shadowInst, inst->instSize);
531 }
533 return(ret);
534 } /* Sa_chanControl */
536 /******************************************************************************
537 * FUNCTION PURPOSE: SALLD Get Channel Stats
538 ******************************************************************************
539 * DESCRIPTION: This function obtains SALLD channel protocol-specific statistics
540 *
541 * int16_t Sa_chanGetStats (
542 * Sa_ChanHandle handle - SALLD channel identifier
543 * uint16_t flags - various control flags
544 * void *stats) - a pointer to protocol_specific statistics
545 *
546 * Return values: sa_ERR_OK
547 * sa_ERR_GEN
548 * sa_ERR_PARAMS
549 * sa_ERR_INV_PROTO_TYPE
550 * sa_ERR_STATS_UNAVAIL
551 *
552 ******************************************************************************/
553 int16_t Sa_chanGetStats (Sa_ChanHandle handle, uint16_t flags, Sa_Stats_t *stats)
554 {
555 int16_t ret = sa_ERR_INV_PROTO_TYPE;
556 salldInst_t *inst = (salldInst_t *)(sa_CONV_OFFSET_TO_ADDR(salldLObj.instPoolBaseAddr, handle));
557 salldInst_t* shadowInst = NULL;
559 /* Invalidate the protocol-specific channel instance */
560 if (SALLD_TEST_STATE_SHARED(inst))
561 {
562 Sa_osalBeginMemAccess(inst, inst->instSize);
564 /* non zero shadow instance offset indicates the presense of shadow instance */
565 if(inst->shadowInstOffset)
566 {
567 shadowInst = (salldInst_t *)(sa_CONV_OFFSET_TO_ADDR(salldLObj.instPoolBaseAddr, inst->shadowInstOffset));
568 Sa_osalBeginMemAccess(shadowInst, inst->instSize);
569 }
570 }
572 if (inst->magic != SALLD_INST_MAGIC_WORD)
573 {
574 if(inst->magic == salld_swiz32(SALLD_INST_MAGIC_WORD))
575 return (sa_ERR_INV_ENDIAN_MODE);
576 else
577 return (sa_ERR_INV_HANDLE);
578 }
580 /* Calls the appropriate msuXyzGetStats function */
581 ret = (*salld_callTblPtr[inst->protoTblIndex]->chanGetStats)(inst, flags, (void *)stats);
583 /* write back the channel specific instance */
584 if (SALLD_TEST_STATE_SHARED(inst))
585 {
586 Sa_osalEndMemAccess(inst, inst->instSize);
588 if(inst->shadowInstOffset)
589 Sa_osalEndMemAccess(shadowInst, inst->instSize);
590 }
592 return(ret);
593 }
595 /******************************************************************************
596 * FUNCTION PURPOSE: Delete an SALLD channel instance
597 ******************************************************************************
598 * DESCRIPTION: This function clears the SALLD chanel instance and returns the base
599 * address of all buffers previously allocated for the SA LLD Channel instance.
600 *
601 * int16_t Sa_chanClose (
602 * Sa_ChanHandle handle, - SALLD channel identifier
603 * void* bases[]) - Output array of the memory buffer base addresses
604 *
605 * Return values: sa_ERR_OK
606 *
607 *
608 ******************************************************************************/
609 int16_t Sa_chanClose (Sa_ChanHandle handle, void* bases[])
610 {
611 salldInst_t *inst = (salldInst_t *)(sa_CONV_OFFSET_TO_ADDR(salldLObj.instPoolBaseAddr, handle));
612 #if !defined(NSS_LITE) && !defined(NSS_LITE2)
613 salldObj_t *sysInst = (salldObj_t *)sa_CONV_OFFSET_TO_ADDR(salldLObj.instPoolBaseAddr, inst->ownerInstOffset);
614 #endif
615 int16_t ret_code;
616 int i;
617 salldInst_t* shadowInst = NULL;
619 /* Invalidate the protocol-specific channel instance */
620 if (SALLD_TEST_STATE_SHARED(inst))
621 {
622 Sa_osalBeginMemAccess(inst, inst->instSize);
624 /* non zero shadow instance offset indicates the presense of shadow instance */
625 if(inst->shadowInstOffset)
626 {
627 shadowInst = (salldInst_t *)(sa_CONV_OFFSET_TO_ADDR(salldLObj.instPoolBaseAddr, inst->shadowInstOffset));
628 Sa_osalBeginMemAccess(shadowInst, inst->instSize);
629 }
630 }
632 if (inst->magic != SALLD_INST_MAGIC_WORD)
633 {
634 if(inst->magic == salld_swiz32(SALLD_INST_MAGIC_WORD))
635 return(sa_ERR_INV_ENDIAN_MODE);
636 else
637 return(sa_ERR_INV_HANDLE);
638 }
640 for (i = 0; i < SALLD_CHAN_NBUF; i++) {
641 bases[i] = (void *) sa_CONV_OFFSET_TO_ADDR(salldLObj.instPoolBaseAddr, inst->memBaseOffsets[i]);
642 }
644 #if !defined(NSS_LITE) && !defined(NSS_LITE2)
645 if (inst->engSelect <= 1)
646 {
647 uint32_t mtCsKey;
648 /* CRITICAL Section Start: The global instance is a shared resource which needs to be
649 * protected from the following:
650 * a) Multiple Cores acccess
651 */
652 Sa_osalMtCsEnter(&mtCsKey);
654 /* Invalidate the Cache Contents */
655 Sa_osalBeginMemAccess(sysInst, sizeof(salldObj_t));
657 if (SALLD_GET_STATE_ENG_SEL_MODE(sysInst) == sa_EngSelMode_LOADBALANCED)
658 {
659 if(sysInst->engCounter[inst->engSelect] > 0)
660 sysInst->engCounter[inst->engSelect]--;
661 }
663 /* Writeback the instance updates */
664 Sa_osalEndMemAccess(sysInst, sizeof(salldObj_t));
666 /* Critical Section End */
667 Sa_osalMtCsExit(mtCsKey);
668 }
669 #endif
671 ret_code = (*salld_callTblPtr[inst->protoTblIndex]->chanClose)(inst);
673 inst->stateBitfield = 0; /* indicate SALLD instance is closed */
674 inst->magic = 0;
676 if (shadowInst)
677 {
678 shadowInst->magic = 0;
679 }
681 /* write back the channel specific instance */
682 if (SALLD_TEST_STATE_SHARED(inst))
683 {
684 Sa_osalEndMemAccess(inst, inst->instSize);
686 if(inst->shadowInstOffset)
687 Sa_osalEndMemAccess(shadowInst, inst->instSize);
688 }
690 return (ret_code);
692 } /* Sa_chanClose */
694 /******************************************************************************
695 * FUNCTION PURPOSE: SALLD Get SW Info
696 ******************************************************************************
697 * DESCRIPTION: This function obtains SA-specific software information
698 *
699 * int16_t Sa_chanGetSwInfo (
700 * Sa_ChanHandle handle - SALLD channel identifier
701 * uint16_t dir - packet directions
702 * Sa_SWInfo_t *pSwInfo) - a pointer to swInfo
703 *
704 * Return values: sa_ERR_OK
705 * sa_ERR_PARAMS
706 * sa_ERR_UNSUPPORTED
707 * sa_ERR_SWINFO_UNAVAIL
708 *
709 ******************************************************************************/
710 int16_t Sa_chanGetSwInfo (Sa_ChanHandle handle, uint16_t dir, Sa_SWInfo_t* pChanSwInfo)
711 {
712 int16_t ret;
713 salldInst_t *inst = (salldInst_t *)(sa_CONV_OFFSET_TO_ADDR(salldLObj.instPoolBaseAddr, handle));
715 if (inst->magic != SALLD_INST_MAGIC_WORD)
716 {
717 if(inst->magic == salld_swiz32(SALLD_INST_MAGIC_WORD))
718 return(sa_ERR_INV_ENDIAN_MODE);
719 else
720 return(sa_ERR_INV_HANDLE);
721 }
723 /* Error Check */
724 if (((!SALLD_TEST_STATE_TX_ON(inst)) && (dir == sa_PKT_DIR_TO_NETWORK)) ||
725 ((!SALLD_TEST_STATE_RX_ON(inst)) && (dir == sa_PKT_DIR_FROM_NETWORK)))
726 {
727 return (sa_ERR_SWINFO_UNAVAIL);
728 }
730 /* Calls the appropriate msuXyzGetStats function */
731 ret = (*salld_callTblPtr[inst->protoTblIndex]->chanGetSwInfo)(inst, dir, pChanSwInfo);
733 return(ret);
734 }
736 /******************************************************************************
737 * FUNCTION PURPOSE: Obtain the SA shadow channel handle
738 ******************************************************************************
739 * DESCRIPTION: This function returns the shadow channel handle. The shadow
740 * channel handle is set to NULL if it does not exist.
741 *
742 * int16_t Sa_chanGetShadowHandle (
743 * Sa_ChanHandle handle - SALLD channel identifier
744 * Sa_ChanHandle *shandle) - Pointer to shadow channel handle
745 *
746 * Return values: sa_ERR_OK
747 * sa_ERR_INV_ENDIAN_MODE
748 * sa_ERR_INV_HANDLE
749 *
750 *****************************************************************************/
751 int16_t Sa_chanGetShadowHandle (Sa_ChanHandle handle, Sa_ChanHandle *shandle)
752 {
753 salldInst_t *inst = (salldInst_t *)(sa_CONV_OFFSET_TO_ADDR(salldLObj.instPoolBaseAddr, handle));
755 if (inst->magic != SALLD_INST_MAGIC_WORD)
756 {
757 if(inst->magic == salld_swiz32(SALLD_INST_MAGIC_WORD))
758 return(sa_ERR_INV_ENDIAN_MODE);
759 else
760 return(sa_ERR_INV_HANDLE);
761 }
763 *shandle = (Sa_ChanHandle)(uintptr_t) inst->shadowInstOffset;
765 return(sa_ERR_OK);
767 }
769 #if !defined(NSS_LITE) && !defined(NSS_LITE2)
771 /* Replay related utility function */
772 /*
773 *
774 * Note that the window is defined by a base and a size. The base is the
775 * lowest index value that can be considered for updating or checking,
776 * while the highest acceptable value for checking is win_base+win_size-1.
777 *
778 * On updating, if the index value is outside the window and "newer" than
779 * the window, then the value of win_base will be adjust so that the
780 * index will "just fit" within the window.
781 *
782 *
783 * | |
784 * |<------- win_size -------->|
785 * | |
786 * -------------+---------------------------+-------------------------
787 * ^ ^
788 * << Older | | Newer >>
789 *
790 * win_base Highest seq idx
791 * we will accept
792 *
793 *
794 * The window "packet present" bits are arranged as a 32-bit uint array.
795 * Each array element tracks 32 index values. The array is circular in
796 * nature so that the top wraps back to the bottom. It is one uint larger
797 * than the maximum window size, allowing for up to 32-bits of "spill-over"
798 * as new indices are added.
799 *
800 * The value of "win_base" is the lowest packet index value that is still
801 * in the window. Any packet coming before this base is not considered.
802 * The position of the bit corresponding to the window base in the physical
803 * bit mask array is determined by two variables; "win_mask_index" is the
804 * index of the 32-bit word in the mask array that hold the bit value,
805 * and "win_mask_bitoff" is the bit offset within that word.
806 *
807 * As the window slides, the flag bits are not moved. Instead, the view
808 * base into the uint array is altered. This is done by incrementing the
809 * value of "win_mask_bitoff" (this is always "win_base & 0x1F"), but it
810 * is tracked separately since it also controls when "win_mask_index" is
811 * incremented. Once the value of "win_mask_bitoff" is greater than 31,
812 * the old array word pointed to by "win_mask_index" is cleared and the
813 * value of "win_mask_index" is incremented. This puts the cleared value
814 * onto the head of the bit mask, and it is then used for new flags at the
815 * top of the window.
816 *
817 *
818 * | 32 bits | 32 bits | 32 bits | 32 bits |
819 * | newest | oldest | older | newer |
820 * +----------------+----------------+----------------+----------------+
821 * ^ ^
822 * | |
823 * win_mask_index |
824 * Window Base
825 *
826 * win_mask_bitoff |<------->|
827 *
828 * --------->| |<------------------- Valid Window -------
829 *
830 *
831 *
832 * The replay related alogritms is based on the concept of RFC4302 Appendix B
833 * It is highly optimized to reduce operation cycles and be PDSP friendly by
834 * Mike Denio.
835 *
836 *
837 */
840 /*******************************************************************************
841 * Function: salld_replay_init
842 *******************************************************************************
843 * DESCRIPTION:
844 * This function is called to initialize the replay context, or to
845 * re-initialize it if an index it entirely out of range.
846 *
847 ******************************************************************************/
848 void salld_replay_init( salldWindow_t* pCtl, uint32_t winBase)
849 {
850 /* Initialize the mask */
851 memset( pCtl->winMask, 0, sizeof(pCtl->winMask));
853 /* Setup the window to be based at the supplied sequence number */
854 pCtl->winMaskIndex = 0;
855 pCtl->winBase = winBase;
857 /*
858 * For simplicity, we align the mask set on the same 32-bit
859 * alignment as the index value. This isn't really necessary,
860 * but it makes the array values a little easier to read, and
861 * doesn't have any affect on code size or performance.
862 */
863 pCtl->winMaskBitoff = winBase & 0x1f;
864 }
866 /*******************************************************************************
867 * Function: salld_replay_check
868 *******************************************************************************
869 * DESCRIPTION:
870 * This function is called to check to see if the packet is within the
871 * window and has not been previously seen.
872 *
873 ******************************************************************************/
874 SALLD_REPLAY_RC_T
875 salld_replay_check(salldWindow_t* pCtl, uint32_t seqNum)
876 {
877 uint32_t seqNumDiff,bitNumber,indexOffset,bitOffset;
879 /* Do the subract first so we are immune to 32-bit wrap */
880 seqNumDiff = seqNum - pCtl->winBase;
882 /* If the delta is "negative", then this packet comes before our base.
883 * It is equivalent to (seqNumDiff > 2^31)
884 * the receive packet is well outside the replay windom, drop it
885 */
886 if( seqNumDiff & (1UL<<31) )
887 return SALLD_REPLAY_RC_OLD;
889 /* See if the packet falls beyond our window */
890 if( seqNumDiff >= pCtl->winSize )
891 return SALLD_REPLAY_RC_NEW;
893 bitNumber = seqNumDiff + pCtl->winMaskBitoff;
895 bitOffset = bitNumber & 0x1F;
896 indexOffset = pCtl->winMaskIndex + (bitNumber>>5);
898 /* The bit mask can wrap */
899 if( indexOffset >= SA_WIN_MASK_SIZE )
900 indexOffset -= SA_WIN_MASK_SIZE;
902 if( pCtl->winMask[indexOffset] & (1<<bitOffset) )
903 return SALLD_REPLAY_RC_DUP;
904 else
905 return SALLD_REPLAY_RC_OK;
906 }
908 /*******************************************************************************
909 * Function: salld_replay_update
910 *******************************************************************************
911 * DESCRIPTION:
912 * This function is called to update the replay state.
913 *
914 * Note: We may need to handle the sequence number wraparound
915 *
916 ******************************************************************************/
917 void
918 salld_replay_update(salldWindow_t* pCtl, uint32_t seqNum)
919 {
920 uint32_t seqNumDiff,bitNumber,indexOffset,bitOffset;
922 /* Do the subract first so we are immune to 32-bit wrap */
923 seqNumDiff = seqNum - pCtl->winBase;
925 /* If the delta is "negative", then this packet comes before our base.
926 * It is equivalent to (seqNumDiff > 2^31)
927 * the receive packet is well outside the replay windom, drop it
928 */
929 if( seqNumDiff & (1UL<<31) )
930 return;
932 // See if the packet falls beyond our window
933 if( seqNumDiff >= pCtl->winSize )
934 {
935 uint32_t slide_delta;
937 slide_delta = seqNumDiff-pCtl->winSize+1;
939 /*
940 * Check the win base wrap around condition
941 */
942 if((pCtl->winBase + slide_delta) < pCtl->winBase)
943 pCtl->winBaseHi++;
945 /*
946 * If we have to slide more than the window size, then its
947 * faster to just re-init.
948 */
949 if( slide_delta >= pCtl->winSize )
950 salld_replay_init( pCtl, seqNum-pCtl->winSize+1 );
951 else
952 {
953 pCtl->winBase += slide_delta;
954 pCtl->winMaskBitoff += slide_delta;
956 /*
957 * If we're still in the same 32-bit word, then we're done, but if
958 * we moved out of the 32-bit word, we need to recover any empty
959 * word for re-use. This means moving the mask index and zeroing
960 * out the value.
961 */
962 while( pCtl->winMaskBitoff>=32 )
963 {
964 pCtl->winMaskBitoff -= 32;
965 pCtl->winMask[pCtl->winMaskIndex] = 0;
966 if( ++pCtl->winMaskIndex >= SA_WIN_MASK_SIZE )
967 pCtl->winMaskIndex = 0;
968 }
969 }
971 /* We know we're alway setting the bit at offset "win_size-1" */
972 seqNumDiff = pCtl->winSize - 1;
973 }
975 /* We now know this packet is inside the window range */
976 bitNumber = seqNumDiff + pCtl->winMaskBitoff;
978 bitOffset = bitNumber & 0x1F;
979 indexOffset = pCtl->winMaskIndex + (bitNumber>>5);
981 /* The bit mask can wrap */
982 if( indexOffset >= SA_WIN_MASK_SIZE )
983 indexOffset -= SA_WIN_MASK_SIZE;
985 pCtl->winMask[indexOffset] |= (1<<bitOffset);
986 }
987 /*******************************************************************************
988 * Function: salld_replay_check_and_update
989 *******************************************************************************
990 * DESCRIPTION:
991 * This function is a combination of checking the index value and then
992 * updating the bit mask array.
993 *
994 * If the packet status is RC_OK or RC_NEW, then the mask array is
995 * updated. When the status is RC_NEW, the window is also shifted
996 * so that the new value is just within the window.
997 *
998 * Return Value:
999 * RC_OLD - Packet is older than the window
1000 * RC_DUP - Packet is inside the window, but has been seen before
1001 * RC_OK - Packet in inside the window and has not been seen
1002 * RC_NEW - Packet is newer than the window
1003 *
1004 ******************************************************************************/
1005 SALLD_REPLAY_RC_T
1006 salld_replay_check_and_update(salldWindow_t* pCtl, uint32_t seqNum)
1007 {
1008 uint32_t seqNumDiff,bitNumber,indexOffset,bitOffset;
1009 SALLD_REPLAY_RC_T rc = SALLD_REPLAY_RC_OK;
1011 /* Do the subract first so we are immune to 32-bit wrap */
1012 seqNumDiff = seqNum - pCtl->winBase;
1014 /* If the delta is "negative", then this packet comes before our base.
1015 * It is equivalent to (seqNumDiff > 2^31)
1016 * the receive packet is well outside the replay windom, drop it
1017 */
1018 if( seqNumDiff & (1UL<<31) )
1019 return SALLD_REPLAY_RC_OLD;
1021 /* See if the packet falls beyond our window */
1022 if( seqNumDiff >= pCtl->winSize )
1023 {
1024 uint32_t slideDelta;
1026 slideDelta = seqNumDiff-pCtl->winSize+1;
1028 /*
1029 * Check the win base wrap around condition
1030 */
1031 if((pCtl->winBase + slideDelta) < pCtl->winBase)
1032 pCtl->winBaseHi++;
1034 /*
1035 * If we have to slide more than the window size, then its
1036 * faster to just re-init.
1037 */
1038 if( slideDelta >= pCtl->winSize )
1039 salld_replay_init(pCtl, seqNum-pCtl->winSize+1 );
1040 else
1041 {
1042 pCtl->winBase += slideDelta;
1043 pCtl->winMaskBitoff += slideDelta;
1045 /*
1046 * If we're still in the same 32-bit word, then we're done, but if
1047 * we moved out of the 32-bit word, we need to recover any empty
1048 * word for re-use. This means moving the mask index and zeroing
1049 * out the value.
1050 */
1051 while( pCtl->winMaskBitoff>=32 )
1052 {
1053 pCtl->winMaskBitoff -= 32;
1054 pCtl->winMask[pCtl->winMaskIndex] = 0;
1055 if( ++pCtl->winMaskIndex == SA_WIN_MASK_SIZE )
1056 pCtl->winMaskIndex = 0;
1057 }
1058 }
1060 /* We know we're alway setting the bit at offset "winSize-1" */
1061 seqNumDiff = pCtl->winSize - 1;
1063 /* The state here is SALLD_REPLAY_RC_NEW */
1064 rc = SALLD_REPLAY_RC_NEW;
1065 }
1067 /* We now know this packet is inside the window range */
1068 bitNumber = seqNumDiff + pCtl->winMaskBitoff;
1070 bitOffset = bitNumber & 0x1F;
1071 indexOffset = pCtl->winMaskIndex + (bitNumber>>5);
1073 /* The bit mask can wrap */
1074 if( indexOffset >= SA_WIN_MASK_SIZE )
1075 indexOffset -= SA_WIN_MASK_SIZE;
1077 if( pCtl->winMask[indexOffset] & (1<<bitOffset) )
1078 return SALLD_REPLAY_RC_DUP;
1080 pCtl->winMask[indexOffset] |= (1<<bitOffset);
1081 return rc;
1082 }
1084 /*******************************************************************************
1085 * Function: salld_replay_is_all_received
1086 *******************************************************************************
1087 * DESCRIPTION:
1088 * This function is called to check whether all packets up to the specified
1089 * sequence number has been received
1090 *
1091 * Return: TRUE - all packets have been received
1092 * FALSE - Otherwise
1093 *
1094 ******************************************************************************/
1095 uint16_t salld_replay_is_all_received(salldWindow_t* pCtl, uint32_t seqNum)
1096 {
1097 uint32_t seqNumDiff,bitNumber,indexOffset,bitOffset, mask, mask1, mask2;
1098 uint16_t index;
1100 if (pCtl->winBase >= seqNum)
1101 {
1102 /*
1103 * The winBase has moved across the sequence number.
1104 * No packets with lower sequence number is allowed
1105 */
1106 return TRUE;
1107 }
1109 seqNumDiff = seqNum - pCtl->winBase;
1111 bitNumber = seqNumDiff + pCtl->winMaskBitoff;
1112 bitOffset = bitNumber & 0x1F;
1113 indexOffset = pCtl->winMaskIndex + (bitNumber>>5);
1115 /* The bit mask can wrap */
1116 if( indexOffset >= SA_WIN_MASK_SIZE )
1117 indexOffset -= SA_WIN_MASK_SIZE;
1119 mask1 = (1<<(bitOffset + 1)) - 1;
1120 mask2 = (1<<(pCtl->winMaskBitoff + 1)) - 1;
1122 if (indexOffset == pCtl->winMaskIndex)
1123 {
1124 mask = mask1 ^ mask2;
1126 if((pCtl->winMask[indexOffset] & mask) == mask)
1127 return TRUE;
1128 }
1129 else
1130 {
1131 mask = 0xFFFFFFFF ^ mask2;
1132 if((pCtl->winMask[pCtl->winMaskIndex] & mask) != mask)
1133 return FALSE;
1135 index = pCtl->winMaskIndex + 1;
1137 if( index >= SA_WIN_MASK_SIZE )
1138 index -= SA_WIN_MASK_SIZE;
1140 if (index > indexOffset)
1141 {
1142 while (index < (SA_WIN_MASK_SIZE - 1))
1143 {
1144 if(pCtl->winMask[index % SA_WIN_MASK_SIZE] != 0xFFFFFFFF)
1145 return FALSE;
1146 index++;
1147 }
1148 index = 0;
1149 }
1151 while (index < indexOffset)
1152 {
1153 if(pCtl->winMask[index % SA_WIN_MASK_SIZE] != 0xFFFFFFFF)
1154 return FALSE;
1155 index++;
1156 }
1158 if((pCtl->winMask[index % SA_WIN_MASK_SIZE] & mask1) == mask1)
1159 return TRUE;
1160 }
1162 return FALSE;
1164 }
1166 /******************************************************************************
1167 * Function: ones_complement_chksum
1168 ******************************************************************************
1169 * Description: Calculate an Internet style one's complement checksum
1170 *
1171 ******************************************************************************/
1172 static inline uint16_t salld_ones_complement_chksum ( uint16_t *p_data, uint16_t len )
1173 {
1174 uint32_t chksum = 0;
1176 while (len > 0)
1177 {
1178 chksum += (uint32_t)pktRead16bits_m ((tword *)p_data,0);
1179 p_data++;
1180 len--;
1181 }
1182 chksum = (chksum >> 16) + (chksum & 0xFFFF); /* add in carry */
1183 chksum += (chksum >> 16); /* maybe one more */
1184 return (uint16_t)chksum;
1186 } /* end of salld_ones_complement_chksum() */
1188 /**************************************************************************************
1189 * FUNCTION PURPOSE: Compute and insert the ipv4 checksum
1190 **************************************************************************************
1191 * DESCRIPTION: Compute and insert the ipv4 checksum
1192 **************************************************************************************/
1193 void salld_set_ipv4_chksum (tword *data)
1194 {
1195 uint16_t hdr_len; /* Hdr Length in 16-bit word */
1196 uint16_t ip_hdr_chksum;
1198 /* calculate IP header length */
1199 hdr_len = (pktRead8bits_m(data, IPV4_BYTE_OFFSET_VER_HLEN) & IPV4_HLEN_MASK) << 1;
1201 pktWrite16bits_m(data, IPV4_BYTE_OFFSET_HDR_CHKSUM, 0);
1204 /* Length for IP Checksum calculation should be in terms of 16-bit twords only */
1205 ip_hdr_chksum = salld_ones_complement_chksum ((uint16_t *)data, hdr_len);
1207 pktWrite16bits_m(data, IPV4_BYTE_OFFSET_HDR_CHKSUM, ~ip_hdr_chksum);
1209 } /* salld_set_ipv4_chksum */
1211 #endif
1213 /****************************************************************************
1214 * FUNCTION PURPOSE: SALLD update security context information at the shadow
1215 * instance
1216 ****************************************************************************
1217 * DESCRIPTION: Pouplate and update the security context information at the
1218 * shadow instance which is used by another processor running in
1219 * opposite Endian mode.
1220 *
1221 * void salld_update_shadow_scInfo(
1222 * Sa_ScReqInfo_t* srcInfo, -> Pointer to the source
1223 * Sa_ScReqInfo_t* destInfo -> Pointer to the destination
1224 * )
1225 * Return values: None
1226 *
1227 ***************************************************************************/
1228 void salld_update_shadow_scInfo(Sa_ScReqInfo_t *srcInfo, Sa_ScReqInfo_t *destInfo)
1229 {
1230 destInfo->scSize = SALLD_SWIZ(srcInfo->scSize);
1231 destInfo->scID = SALLD_SWIZ(srcInfo->scID);
1232 destInfo->scBuf = (uintptr_t )SALLD_SWIZ((uintptr_t)srcInfo->scBuf);
1233 }
1235 /****************************************************************************
1236 * FUNCTION PURPOSE: SALLD update software information at the shadow
1237 * instance
1238 ****************************************************************************
1239 * DESCRIPTION: Pouplate and update the software information at the
1240 * shadow instance which is used by another processor running in
1241 * opposite Endian mode.
1242 *
1243 * void salld_update_shadow_swInfo(
1244 * Sa_SWInfo_t* srcInfo, -> Pointer to the source
1245 * Sa_SWInfo_t* destInfo -> Pointer to the destination
1246 * )
1247 * Return values: None
1248 *
1249 ***************************************************************************/
1250 void salld_update_shadow_swInfo(Sa_SWInfo_t *srcInfo, Sa_SWInfo_t *destInfo)
1251 {
1252 int i;
1254 destInfo->size = SALLD_SWIZ(srcInfo->size);
1256 for (i = 0; i < srcInfo->size; i++)
1257 {
1258 destInfo->swInfo[i] = SALLD_SWIZ(srcInfo->swInfo[i]);
1259 }
1260 }
1262 /****************************************************************************
1263 * FUNCTION PURPOSE: SALLD update destination information at the shadow
1264 * instance
1265 ****************************************************************************
1266 * DESCRIPTION: Pouplate and update the destination information at the
1267 * shadow instance which is used by another processor running in
1268 * opposite Endian mode.
1269 *
1270 * void salld_update_shadow_destInfo(
1271 * Sa_DestInfo_t* srcInfo, -> Pointer to the source
1272 * Sa_DestInfo_t* destInfo -> Pointer to the destination
1273 * )
1274 * Return values: None
1275 *
1276 ***************************************************************************/
1277 void salld_update_shadow_destInfo(Sa_DestInfo_t *srcInfo, Sa_DestInfo_t *destInfo)
1278 {
1279 destInfo->flowID = SALLD_SWIZ(srcInfo->flowID);
1280 destInfo->queueID = SALLD_SWIZ(srcInfo->queueID);
1281 destInfo->swInfo0 = SALLD_SWIZ(srcInfo->swInfo0);
1282 destInfo->swInfo1 = SALLD_SWIZ(srcInfo->swInfo1);
1283 }
1285 /* nothing past this point */