Merge branch 'next' of git://git.denx.de/u-boot-video
[platform/kernel/u-boot.git] / arch / arm / cpu / ixp / npe / IxNpeDl.c
1 /**
2  * @file IxNpeDl.c
3  *
4  * @author Intel Corporation
5  * @date 08 January 2002
6  *
7  * @brief This file contains the implementation of the public API for the
8  *        IXP425 NPE Downloader component
9  *
10  *
11  * @par
12  * IXP400 SW Release version 2.0
13  *
14  * -- Copyright Notice --
15  *
16  * @par
17  * Copyright 2001-2005, Intel Corporation.
18  * All rights reserved.
19  *
20  * @par
21  * Redistribution and use in source and binary forms, with or without
22  * modification, are permitted provided that the following conditions
23  * are met:
24  * 1. Redistributions of source code must retain the above copyright
25  *    notice, this list of conditions and the following disclaimer.
26  * 2. Redistributions in binary form must reproduce the above copyright
27  *    notice, this list of conditions and the following disclaimer in the
28  *    documentation and/or other materials provided with the distribution.
29  * 3. Neither the name of the Intel Corporation nor the names of its contributors
30  *    may be used to endorse or promote products derived from this software
31  *    without specific prior written permission.
32  *
33  * @par
34  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
35  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
36  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
37  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
38  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
39  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
40  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
41  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
42  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
43  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44  * SUCH DAMAGE.
45  *
46  * @par
47  * -- End of Copyright Notice --
48 */
49
50 /*
51  * Put the system defined include files required
52  */
53
54 /*
55  * Put the user defined include files required
56  */
57 #include "IxNpeDl.h"
58 #include "IxNpeDlImageMgr_p.h"
59 #include "IxNpeDlNpeMgr_p.h"
60 #include "IxNpeDlMacros_p.h"
61 #include "IxFeatureCtrl.h"
62 #include "IxOsal.h"
63 /*
64  * #defines used in this file
65  */
66  #define IMAGEID_MAJOR_NUMBER_DEFAULT 0
67  #define IMAGEID_MINOR_NUMBER_DEFAULT 0
68
69 /*
70  * Typedefs whose scope is limited to this file.
71  */
72 typedef struct
73 {
74     BOOL validImage;
75     IxNpeDlImageId imageId;
76 } IxNpeDlNpeState;
77
78 /* module statistics counters */
79 typedef struct
80 {
81     UINT32 attemptedDownloads;
82     UINT32 successfulDownloads;
83     UINT32 criticalFailDownloads;
84 } IxNpeDlStats;
85
86 /*
87  * Variable declarations global to this file only.  Externs are followed
88  * by static variables.
89  */
90 static IxNpeDlNpeState ixNpeDlNpeState[IX_NPEDL_NPEID_MAX] =
91 {
92     {FALSE, {IX_NPEDL_NPEID_MAX, 0, 0, 0}},
93     {FALSE, {IX_NPEDL_NPEID_MAX, 0, 0, 0}},
94     {FALSE, {IX_NPEDL_NPEID_MAX, 0, 0, 0}}
95 };
96
97 static IxNpeDlStats ixNpeDlStats;
98
99 /*
100  * Software guard to prevent NPE from being started multiple times.
101  */
102 static BOOL ixNpeDlNpeStarted[IX_NPEDL_NPEID_MAX] ={FALSE, FALSE, FALSE} ;
103
104
105 /*
106  * static function prototypes.
107  */
108 PRIVATE IX_STATUS
109 ixNpeDlNpeInitAndStartInternal (UINT32 *imageLibrary, UINT32 imageId);
110
111 /*
112  * Function definition: ixNpeDlImageDownload
113  */
114 PUBLIC IX_STATUS
115 ixNpeDlImageDownload (IxNpeDlImageId *imageIdPtr,
116                       BOOL verify)
117 {
118     UINT32        imageSize;
119     UINT32       *imageCodePtr  = NULL;
120     IX_STATUS     status;
121     IxNpeDlNpeId  npeId           = imageIdPtr->npeId;
122
123     IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
124                      "Entering ixNpeDlImageDownload\n");
125
126     ixNpeDlStats.attemptedDownloads++;
127
128     /* Check input parameters */
129     if ((npeId >= IX_NPEDL_NPEID_MAX) || (npeId < 0))
130     {
131         status = IX_NPEDL_PARAM_ERR;
132         IX_NPEDL_ERROR_REPORT ("ixNpeDlImageDownload - invalid parameter\n");
133     }
134     else
135     {
136         /* Ensure initialisation has been completed */
137         ixNpeDlNpeMgrInit();
138
139         /* If not IXP42X A0 stepping, proceed to check for existence of npe's */
140         if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
141              (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
142             || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
143         {
144             if (npeId == IX_NPEDL_NPEID_NPEA)
145             {
146                 if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA) ==
147                     IX_FEATURE_CTRL_COMPONENT_DISABLED)
148                 {
149                     IX_NPEDL_WARNING_REPORT("Warning: the NPE A component you specified does"
150                                             " not exist\n");
151                     return IX_SUCCESS;
152                 }
153             } /* end of if(npeId) */
154             else if (npeId == IX_NPEDL_NPEID_NPEB)
155             {
156                 if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB)==
157                     IX_FEATURE_CTRL_COMPONENT_DISABLED)
158                 {
159                     IX_NPEDL_WARNING_REPORT("Warning: the NPE B component you specified"
160                                             " does not exist\n");
161                     return IX_SUCCESS;
162                 }
163             } /* end of elseif(npeId) */
164             else if (npeId == IX_NPEDL_NPEID_NPEC)
165             {
166                 if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC)==
167                     IX_FEATURE_CTRL_COMPONENT_DISABLED)
168                 {
169                     IX_NPEDL_WARNING_REPORT("Warning: the NPE C component you specified"
170                                             " does not exist\n");
171                     return IX_SUCCESS;
172                 }
173             } /* end of elseif(npeId) */
174         } /* end of if(IX_FEATURE_CTRL_SILICON_TYPE_B0) */ /*End of Silicon Type Check*/
175
176         /* stop and reset the NPE */
177         if (IX_SUCCESS != ixNpeDlNpeStopAndReset (npeId))
178         {
179             IX_NPEDL_ERROR_REPORT ("Failed to stop and reset NPE\n");
180             return IX_FAIL;
181         }
182
183         /* Locate image */
184         status = ixNpeDlImageMgrImageLocate (imageIdPtr, &imageCodePtr,
185                                              &imageSize);
186         if (IX_SUCCESS == status)
187         {
188             /*
189              * If download was successful, store image Id in list of
190              * currently loaded images. If a critical error occured
191              * during download, record that the NPE has an invalid image
192              */
193             status = ixNpeDlNpeMgrImageLoad (npeId, imageCodePtr,
194                                              verify);
195             if (IX_SUCCESS == status)
196             {
197                 ixNpeDlNpeState[npeId].imageId = *imageIdPtr;
198                 ixNpeDlNpeState[npeId].validImage = TRUE;
199                 ixNpeDlStats.successfulDownloads++;
200
201                 status =  ixNpeDlNpeExecutionStart (npeId);
202             }
203             else if ((status == IX_NPEDL_CRITICAL_NPE_ERR) ||
204                      (status == IX_NPEDL_CRITICAL_MICROCODE_ERR))
205             {
206                 ixNpeDlNpeState[npeId].imageId = *imageIdPtr;
207                 ixNpeDlNpeState[npeId].validImage = FALSE;
208                 ixNpeDlStats.criticalFailDownloads++;
209             }
210         } /* end of if(IX_SUCCESS) */ /* condition: image located successfully in microcode image */
211     } /* end of if-else(npeId) */ /* condition: parameter checks ok */
212
213     IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
214                      "Exiting ixNpeDlImageDownload : status = %d\n", status);
215     return status;
216 }
217
218 /*
219  * Function definition: ixNpeDlAvailableImagesCountGet
220  */
221 PUBLIC IX_STATUS
222 ixNpeDlAvailableImagesCountGet (UINT32 *numImagesPtr)
223 {
224     IX_STATUS status;
225
226     IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
227                      "Entering ixNpeDlAvailableImagesCountGet\n");
228
229     /* Check input parameters */
230     if (numImagesPtr == NULL)
231     {
232         status = IX_NPEDL_PARAM_ERR;
233         IX_NPEDL_ERROR_REPORT ("ixNpeDlAvailableImagesCountGet - "
234                                "invalid parameter\n");
235     }
236     else
237     {
238         /*
239          * Use ImageMgr module to get no. of images listed in Image Library Header.
240          * If NULL is passed as imageListPtr parameter to following function,
241          * it will only fill number of images into numImagesPtr
242          */
243         status = ixNpeDlImageMgrImageListExtract (NULL, numImagesPtr);
244     } /* end of if-else(numImagesPtr) */
245
246     IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
247                      "Exiting ixNpeDlAvailableImagesCountGet : "
248                      "status = %d\n", status);
249     return status;
250 }
251
252 /*
253  * Function definition: ixNpeDlAvailableImagesListGet
254  */
255 PUBLIC IX_STATUS
256 ixNpeDlAvailableImagesListGet (IxNpeDlImageId *imageIdListPtr,
257                                UINT32 *listSizePtr)
258 {
259     IX_STATUS status;
260
261     IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
262                      "Entering ixNpeDlAvailableImagesListGet\n");
263
264     /* Check input parameters */
265     if ((imageIdListPtr == NULL) || (listSizePtr == NULL))
266     {
267         status = IX_NPEDL_PARAM_ERR;
268         IX_NPEDL_ERROR_REPORT ("ixNpeDlAvailableImagesListGet - "
269                                "invalid parameter\n");
270     }
271     else
272     {
273         /* Call ImageMgr to get list of images listed in Image Library Header */
274         status = ixNpeDlImageMgrImageListExtract (imageIdListPtr,
275                                                   listSizePtr);
276     } /* end of if-else(imageIdListPtr) */
277
278     IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
279                      "Exiting ixNpeDlAvailableImagesListGet : status = %d\n",
280                      status);
281     return status;
282 }
283
284 /*
285  * Function definition: ixNpeDlLoadedImageGet
286  */
287 PUBLIC IX_STATUS
288 ixNpeDlLoadedImageGet (IxNpeDlNpeId npeId,
289                        IxNpeDlImageId *imageIdPtr)
290 {
291     IX_STATUS status = IX_SUCCESS;
292
293     IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
294                      "Entering ixNpeDlLoadedImageGet\n");
295
296     /* Check input parameters */
297     if ((npeId >= IX_NPEDL_NPEID_MAX) || (npeId < 0) || (imageIdPtr == NULL))
298     {
299         status = IX_NPEDL_PARAM_ERR;
300         IX_NPEDL_ERROR_REPORT ("ixNpeDlLoadedImageGet - invalid parameter\n");
301     }
302     else
303     {
304
305          /* If not IXP42X A0 stepping, proceed to check for existence of npe's */
306          if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
307               (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
308              || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
309         {
310             if (npeId == IX_NPEDL_NPEID_NPEA &&
311                 (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA) ==
312                  IX_FEATURE_CTRL_COMPONENT_DISABLED))
313             {
314                 IX_NPEDL_WARNING_REPORT("Warning: the NPE A component you specified does"
315                                         " not exist\n");
316                 return IX_SUCCESS;
317             } /* end of if(npeId) */
318
319             if (npeId == IX_NPEDL_NPEID_NPEB &&
320                 (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB) ==
321                  IX_FEATURE_CTRL_COMPONENT_DISABLED))
322             {
323                 IX_NPEDL_WARNING_REPORT("Warning: the NPE B component you specified does"
324                                         " not exist\n");
325                 return IX_SUCCESS;
326             } /* end of if(npeId) */
327
328             if (npeId == IX_NPEDL_NPEID_NPEC &&
329                 (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC) ==
330                  IX_FEATURE_CTRL_COMPONENT_DISABLED))
331             {
332                 IX_NPEDL_WARNING_REPORT("Warning: the NPE C component you specified does"
333                                         " not exist\n");
334                 return IX_SUCCESS;
335             } /* end of if(npeId) */
336         } /* end of if not IXP42x-A0 silicon */
337
338         if (ixNpeDlNpeState[npeId].validImage)
339         {
340             /* use npeId to get imageId from list of currently loaded
341                images */
342             *imageIdPtr = ixNpeDlNpeState[npeId].imageId;
343         }
344         else
345         {
346             status = IX_FAIL;
347         } /* end of if-else(ixNpeDlNpeState) */
348     } /* end of if-else(npeId) */
349
350     IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
351                      "Exiting ixNpeDlLoadedImageGet : status = %d\n",
352                      status);
353     return status;
354 }
355
356 /*
357  * Function definition: ixNpeDlLatestImageGet
358  */
359 PUBLIC IX_STATUS
360 ixNpeDlLatestImageGet (
361     IxNpeDlNpeId npeId,
362     IxNpeDlFunctionalityId functionalityId,
363     IxNpeDlImageId *imageIdPtr)
364 {
365     IX_STATUS status;
366
367     IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
368                      "Entering ixNpeDlLatestImageGet\n");
369
370     /* Check input parameters */
371     if ((npeId >= IX_NPEDL_NPEID_MAX) ||
372         (npeId < 0) ||
373         (imageIdPtr == NULL))
374     {
375         status = IX_NPEDL_PARAM_ERR;
376         IX_NPEDL_ERROR_REPORT ("ixNpeDlLatestImageGet - "
377                                "invalid parameter\n");
378     } /* end of if(npeId) */
379     else
380     {
381
382         /* If not IXP42X A0 stepping, proceed to check for existence of npe's */
383         if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
384              (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
385             || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
386         {
387             if (npeId == IX_NPEDL_NPEID_NPEA &&
388                 (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA) ==
389                  IX_FEATURE_CTRL_COMPONENT_DISABLED))
390             {
391                 IX_NPEDL_WARNING_REPORT("Warning: the NPE A component you specified does"
392                                         " not exist\n");
393                 return IX_SUCCESS;
394             } /* end of if(npeId) */
395
396             if (npeId == IX_NPEDL_NPEID_NPEB &&
397                 (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB) ==
398                  IX_FEATURE_CTRL_COMPONENT_DISABLED))
399             {
400                 IX_NPEDL_WARNING_REPORT("Warning: the NPE B component you specified does"
401                                         " not exist\n");
402                 return IX_SUCCESS;
403             } /* end of if(npeId) */
404
405             if (npeId == IX_NPEDL_NPEID_NPEC &&
406                 (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC) ==
407                  IX_FEATURE_CTRL_COMPONENT_DISABLED))
408             {
409                 IX_NPEDL_WARNING_REPORT("Warning: the NPE C component you specified does"
410                                         " not exist\n");
411                 return IX_SUCCESS;
412             } /* end of if(npeId) */
413         } /* end of if not IXP42x-A0 silicon */
414
415         imageIdPtr->npeId = npeId;
416         imageIdPtr->functionalityId = functionalityId;
417         imageIdPtr->major = IMAGEID_MAJOR_NUMBER_DEFAULT;
418         imageIdPtr->minor = IMAGEID_MINOR_NUMBER_DEFAULT;
419         /* Call ImageMgr to get list of images listed in Image Library Header */
420         status = ixNpeDlImageMgrLatestImageExtract(imageIdPtr);
421     } /* end of if-else(npeId) */
422
423     IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
424                      "Exiting ixNpeDlLatestImageGet : status = %d\n",
425                      status);
426
427     return status;
428 }
429
430 /*
431  * Function definition: ixNpeDlNpeStopAndReset
432  */
433 PUBLIC IX_STATUS
434 ixNpeDlNpeStopAndReset (IxNpeDlNpeId npeId)
435 {
436     IX_STATUS status = IX_SUCCESS;
437
438     IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
439                      "Entering ixNpeDlNpeStopAndReset\n");
440
441     /* Ensure initialisation has been completed */
442     ixNpeDlNpeMgrInit();
443
444     /* If not IXP42X A0 stepping, proceed to check for existence of npe's */
445     if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
446          (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
447         || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
448     {
449         /*
450          * Check whether NPE is present
451          */
452         if (IX_NPEDL_NPEID_NPEA == npeId)
453         {
454             /* Check whether NPE A is present */
455             if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA)==
456                 IX_FEATURE_CTRL_COMPONENT_DISABLED)
457             {
458                 /* NPE A does not present */
459                 IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeStopAndReset - Warning:NPEA does not present.\n");
460                 return IX_SUCCESS;
461             }
462         } /* end of if(IX_NPEDL_NPEID_NPEA) */
463         else if (IX_NPEDL_NPEID_NPEB == npeId)
464         {
465             /* Check whether NPE B is present */
466             if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB)==
467                 IX_FEATURE_CTRL_COMPONENT_DISABLED)
468             {
469                 /* NPE B does not present */
470                 IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeStopAndReset - Warning:NPEB does not present.\n");
471                 return IX_SUCCESS;
472             }
473         } /* end of elseif(IX_NPEDL_NPEID_NPEB) */
474         else if (IX_NPEDL_NPEID_NPEC == npeId)
475         {
476             /* Check whether NPE C is present */
477             if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC)==
478                 IX_FEATURE_CTRL_COMPONENT_DISABLED)
479             {
480                 /* NPE C does not present */
481                 IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeStopAndReset - Warning:NPEC does not present.\n");
482                 return IX_SUCCESS;
483             }
484         } /* end of elseif(IX_NPEDL_NPEID_NPEC) */
485         else
486         {
487             /* Invalid NPE ID */
488             IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeStopAndReset - invalid Npe ID\n");
489             status = IX_NPEDL_PARAM_ERR;
490         } /* end of if-else(IX_NPEDL_NPEID_NPEC) */
491     } /* end of if not IXP42x-A0 Silicon */
492
493     if (status == IX_SUCCESS)
494     {
495         /* call NpeMgr function to stop the NPE */
496         status = ixNpeDlNpeMgrNpeStop (npeId);
497         if (status == IX_SUCCESS)
498         {
499             /* call NpeMgr function to reset the NPE */
500             status = ixNpeDlNpeMgrNpeReset (npeId);
501         }
502     } /* end of if(status) */
503
504     IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
505                      "Exiting ixNpeDlNpeStopAndReset : status = %d\n", status);
506
507     if (IX_SUCCESS == status)
508     {
509         /* Indicate NPE has been stopped */
510         ixNpeDlNpeStarted[npeId] = FALSE ;
511     }
512
513     return status;
514 }
515
516 /*
517  * Function definition: ixNpeDlNpeExecutionStart
518  */
519 PUBLIC IX_STATUS
520 ixNpeDlNpeExecutionStart (IxNpeDlNpeId npeId)
521 {
522     IX_STATUS status = IX_SUCCESS;
523
524     IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
525                      "Entering ixNpeDlNpeExecutionStart\n");
526
527     /* If not IXP42X A0 stepping, proceed to check for existence of npe's */
528     if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
529          (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
530         || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
531     {
532         /*
533          * Check whether NPE is present
534          */
535         if (IX_NPEDL_NPEID_NPEA == npeId)
536         {
537             /* Check whether NPE A is present */
538             if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA)==
539                 IX_FEATURE_CTRL_COMPONENT_DISABLED)
540             {
541                 /* NPE A does not present */
542                 IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStart - Warning:NPEA does not present.\n");
543                 return IX_SUCCESS;
544             }
545         } /* end of if(IX_NPEDL_NPEID_NPEA) */
546         else if (IX_NPEDL_NPEID_NPEB == npeId)
547         {
548             /* Check whether NPE B is present */
549             if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB)==
550                 IX_FEATURE_CTRL_COMPONENT_DISABLED)
551             {
552                 /* NPE B does not present */
553                 IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStart - Warning:NPEB does not present.\n");
554                 return IX_SUCCESS;
555             }
556         } /* end of elseif(IX_NPEDL_NPEID_NPEB) */
557         else if (IX_NPEDL_NPEID_NPEC ==  npeId)
558         {
559             /* Check whether NPE C is present */
560             if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC)==
561                 IX_FEATURE_CTRL_COMPONENT_DISABLED)
562             {
563                 /* NPE C does not present */
564                 IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStart - Warning:NPEC does not present.\n");
565                 return IX_SUCCESS;
566             }
567         } /* end of elseif(IX_NPEDL_NPEID_NPEC) */
568         else
569         {
570             /* Invalid NPE ID */
571             IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeExecutionStart - invalid Npe ID\n");
572             return IX_NPEDL_PARAM_ERR;
573         } /* end of if-else(IX_NPEDL_NPEID_NPEC) */
574     } /* end of if not IXP42x-A0 Silicon */
575
576     if (TRUE == ixNpeDlNpeStarted[npeId])
577     {
578         /* NPE has been started. */
579         return IX_SUCCESS ;
580     }
581
582     /* Ensure initialisation has been completed */
583     ixNpeDlNpeMgrInit();
584
585     /* call NpeMgr function to start the NPE */
586     status = ixNpeDlNpeMgrNpeStart (npeId);
587
588     if (IX_SUCCESS == status)
589     {
590         /* Indicate NPE has started */
591         ixNpeDlNpeStarted[npeId] = TRUE ;
592     }
593
594     IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
595                      "Exiting ixNpeDlNpeExecutionStart : status = %d\n",
596                      status);
597
598     return status;
599 }
600
601 /*
602  * Function definition: ixNpeDlNpeExecutionStop
603  */
604 PUBLIC IX_STATUS
605 ixNpeDlNpeExecutionStop (IxNpeDlNpeId npeId)
606 {
607     IX_STATUS status = IX_SUCCESS;
608
609     IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
610                      "Entering ixNpeDlNpeExecutionStop\n");
611
612     /* Ensure initialisation has been completed */
613     ixNpeDlNpeMgrInit();
614
615     /* If not IXP42X A0 stepping, proceed to check for existence of npe's */
616     if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
617          (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
618         || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
619     {
620         /*
621          * Check whether NPE is present
622          */
623         if (IX_NPEDL_NPEID_NPEA == npeId)
624         {
625             /* Check whether NPE A is present */
626             if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA)==
627                 IX_FEATURE_CTRL_COMPONENT_DISABLED)
628             {
629                 /* NPE A does not present */
630                 IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStop - Warning:NPEA does not present.\n");
631                 return IX_SUCCESS;
632             }
633         } /* end of if(IX_NPEDL_NPEID_NPEA) */
634         else if (IX_NPEDL_NPEID_NPEB == npeId)
635         {
636             /* Check whether NPE B is present */
637             if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB)==
638                 IX_FEATURE_CTRL_COMPONENT_DISABLED)
639             {
640                 /* NPE B does not present */
641                 IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStop - Warning:NPEB does not present.\n");
642                 return IX_SUCCESS;
643             }
644         } /* end of elseif(IX_NPEDL_NPEID_NPEB) */
645         else if (IX_NPEDL_NPEID_NPEC == npeId)
646         {
647             /* Check whether NPE C is present */
648             if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC)==
649                 IX_FEATURE_CTRL_COMPONENT_DISABLED)
650             {
651                 /* NPE C does not present */
652                 IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStop - Warning:NPEC does not present.\n");
653                 return IX_SUCCESS;
654             }
655         } /* end of elseif(IX_NPEDL_NPEID_NPEC) */
656         else
657         {
658             /* Invalid NPE ID */
659             IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeExecutionStop - invalid Npe ID\n");
660             status = IX_NPEDL_PARAM_ERR;
661         } /* end of if-else(IX_NPEDL_NPEID_NPEC) */
662     } /* end of if not IXP42X-AO Silicon */
663
664     if (status == IX_SUCCESS)
665     {
666         /* call NpeMgr function to stop the NPE */
667         status = ixNpeDlNpeMgrNpeStop (npeId);
668     }
669
670     IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
671                      "Exiting ixNpeDlNpeExecutionStop : status = %d\n",
672                      status);
673
674     if (IX_SUCCESS == status)
675     {
676         /* Indicate NPE has been stopped */
677         ixNpeDlNpeStarted[npeId] = FALSE ;
678     }
679
680     return status;
681 }
682
683 /*
684  * Function definition: ixNpeDlUnload
685  */
686 PUBLIC IX_STATUS
687 ixNpeDlUnload (void)
688 {
689     IX_STATUS status;
690
691     IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
692                      "Entering ixNpeDlUnload\n");
693
694     status = ixNpeDlNpeMgrUninit();
695
696     IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
697                      "Exiting ixNpeDlUnload : status = %d\n",
698                      status);
699     return status;
700 }
701
702 /*
703  * Function definition: ixNpeDlStatsShow
704  */
705 PUBLIC void
706 ixNpeDlStatsShow (void)
707 {
708     ixOsalLog (IX_OSAL_LOG_LVL_USER,
709                IX_OSAL_LOG_DEV_STDOUT,
710                "\nixNpeDlStatsShow:\n"
711                "\tDownloads Attempted by user: %u\n"
712                "\tSuccessful Downloads: %u\n"
713                "\tFailed Downloads (due to Critical Error): %u\n\n",
714                ixNpeDlStats.attemptedDownloads,
715                ixNpeDlStats.successfulDownloads,
716                ixNpeDlStats.criticalFailDownloads,
717                0,0,0);
718
719     ixNpeDlImageMgrStatsShow ();
720     ixNpeDlNpeMgrStatsShow ();
721 }
722
723 /*
724  * Function definition: ixNpeDlStatsReset
725  */
726 PUBLIC void
727 ixNpeDlStatsReset (void)
728 {
729     ixNpeDlStats.attemptedDownloads = 0;
730     ixNpeDlStats.successfulDownloads = 0;
731     ixNpeDlStats.criticalFailDownloads = 0;
732
733     ixNpeDlImageMgrStatsReset ();
734     ixNpeDlNpeMgrStatsReset ();
735 }
736
737 /*
738  * Function definition: ixNpeDlNpeInitAndStartInternal
739  */
740 PRIVATE IX_STATUS
741 ixNpeDlNpeInitAndStartInternal (UINT32 *imageLibrary,
742                                 UINT32 imageId)
743 {
744     UINT32        imageSize;
745     UINT32       *imageCodePtr  = NULL;
746     IX_STATUS     status;
747     IxNpeDlNpeId  npeId = IX_NPEDL_NPEID_FROM_IMAGEID_GET(imageId);
748     IxFeatureCtrlDeviceId deviceId = IX_NPEDL_DEVICEID_FROM_IMAGEID_GET(imageId);
749
750     IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
751                      "Entering ixNpeDlNpeInitAndStartInternal\n");
752
753     ixNpeDlStats.attemptedDownloads++;
754
755     /* Check input parameter device correctness */
756     if ((deviceId >= IX_FEATURE_CTRL_DEVICE_TYPE_MAX) ||
757         (deviceId < IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X))
758     {
759         status = IX_NPEDL_PARAM_ERR;
760         IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeInitAndStartInternal - "
761                                "invalid parameter\n");
762     } /* End valid device id checking */
763
764     /* Check input parameters */
765     else if ((npeId >= IX_NPEDL_NPEID_MAX) || (npeId < 0))
766     {
767         status = IX_NPEDL_PARAM_ERR;
768         IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeInitAndStartInternal - "
769                                "invalid parameter\n");
770     }
771
772     else
773     {
774         /* Ensure initialisation has been completed */
775         ixNpeDlNpeMgrInit();
776
777         /* Checking if image being loaded is meant for device that is running.
778          * Image is forward compatible. i.e Image built for IXP42X should run
779          * on IXP46X but not vice versa.*/
780         if (deviceId > (ixFeatureCtrlDeviceRead() & IX_FEATURE_CTRL_DEVICE_TYPE_MASK))
781         {
782             IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeInitAndStartInternal - "
783                                    "Device type mismatch. NPE Image not "
784                                    "meant for device in use \n");
785             return IX_NPEDL_DEVICE_ERR;
786         }/* if statement - matching image device and current device */
787
788         /* If not IXP42X A0 stepping, proceed to check for existence of npe's */
789         if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
790              (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
791             || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
792         {
793             if (npeId == IX_NPEDL_NPEID_NPEA)
794             {
795                 if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA) ==
796                     IX_FEATURE_CTRL_COMPONENT_DISABLED)
797                 {
798                     IX_NPEDL_WARNING_REPORT("Warning: the NPE A component you specified does"
799                                             " not exist\n");
800                     return IX_SUCCESS;
801                 }
802             } /* end of if(npeId) */
803             else if (npeId == IX_NPEDL_NPEID_NPEB)
804             {
805                 if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB)==
806                     IX_FEATURE_CTRL_COMPONENT_DISABLED)
807                 {
808                     IX_NPEDL_WARNING_REPORT("Warning: the NPE B component you specified"
809                                             " does not exist\n");
810                     return IX_SUCCESS;
811                 }
812             } /* end of elseif(npeId) */
813             else if (npeId == IX_NPEDL_NPEID_NPEC)
814             {
815                 if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC)==
816                     IX_FEATURE_CTRL_COMPONENT_DISABLED)
817                 {
818                     IX_NPEDL_WARNING_REPORT("Warning: the NPE C component you specified"
819                                             " does not exist\n");
820                     return IX_SUCCESS;
821                 }
822             } /* end of elseif(npeId) */
823         } /* end of if not IXP42X-A0 Silicon */
824
825         /* stop and reset the NPE */
826         status = ixNpeDlNpeStopAndReset (npeId);
827         if (IX_SUCCESS != status)
828         {
829             IX_NPEDL_ERROR_REPORT ("Failed to stop and reset NPE\n");
830             return status;
831         }
832
833         /* Locate image */
834         status = ixNpeDlImageMgrImageFind (imageLibrary, imageId,
835                                            &imageCodePtr, &imageSize);
836         if (IX_SUCCESS == status)
837         {
838             /*
839              * If download was successful, store image Id in list of
840              * currently loaded images. If a critical error occured
841              * during download, record that the NPE has an invalid image
842              */
843             status = ixNpeDlNpeMgrImageLoad (npeId, imageCodePtr, TRUE);
844             if (IX_SUCCESS == status)
845             {
846                 ixNpeDlNpeState[npeId].validImage = TRUE;
847                 ixNpeDlStats.successfulDownloads++;
848
849                 status = ixNpeDlNpeExecutionStart (npeId);
850             }
851             else if ((status == IX_NPEDL_CRITICAL_NPE_ERR) ||
852                      (status == IX_NPEDL_CRITICAL_MICROCODE_ERR))
853             {
854                 ixNpeDlNpeState[npeId].validImage = FALSE;
855                 ixNpeDlStats.criticalFailDownloads++;
856             }
857
858             /* NOTE - The following section of code is here to support
859              * a deprecated function ixNpeDlLoadedImageGet().  When that
860              * function is removed from the API, this code should be revised.
861              */
862             ixNpeDlNpeState[npeId].imageId.npeId = npeId;
863             ixNpeDlNpeState[npeId].imageId.functionalityId =
864                 IX_NPEDL_FUNCTIONID_FROM_IMAGEID_GET(imageId);
865             ixNpeDlNpeState[npeId].imageId.major =
866                 IX_NPEDL_MAJOR_FROM_IMAGEID_GET(imageId);
867             ixNpeDlNpeState[npeId].imageId.minor =
868                 IX_NPEDL_MINOR_FROM_IMAGEID_GET(imageId);
869         } /* end of if(IX_SUCCESS) */ /* condition: image located successfully in microcode image */
870     } /* end of if-else(npeId-deviceId) */ /* condition: parameter checks ok */
871
872     IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
873                      "Exiting ixNpeDlNpeInitAndStartInternal : "
874                      "status = %d\n", status);
875     return status;
876 }
877
878 /*
879  * Function definition: ixNpeDlCustomImageNpeInitAndStart
880  */
881 PUBLIC IX_STATUS
882 ixNpeDlCustomImageNpeInitAndStart (UINT32 *imageLibrary,
883                                    UINT32 imageId)
884 {
885     IX_STATUS status;
886
887     if (imageLibrary == NULL)
888     {
889         status = IX_NPEDL_PARAM_ERR;
890         IX_NPEDL_ERROR_REPORT ("ixNpeDlCustomImageNpeInitAndStart "
891                                "- invalid parameter\n");
892     }
893     else
894     {
895         status = ixNpeDlNpeInitAndStartInternal (imageLibrary, imageId);
896     } /* end of if-else(imageLibrary) */
897
898     return status;
899 }
900
901 /*
902  * Function definition: ixNpeDlNpeInitAndStart
903  */
904 PUBLIC IX_STATUS
905 ixNpeDlNpeInitAndStart (UINT32 imageId)
906 {
907     return ixNpeDlNpeInitAndStartInternal (NULL, imageId);
908 }
909
910 /*
911  * Function definition: ixNpeDlLoadedImageFunctionalityGet
912  */
913 PUBLIC IX_STATUS
914 ixNpeDlLoadedImageFunctionalityGet (IxNpeDlNpeId npeId,
915                                     UINT8 *functionalityId)
916 {
917     /* Check input parameters */
918     if ((npeId >= IX_NPEDL_NPEID_MAX) || (npeId < 0))
919     {
920         IX_NPEDL_ERROR_REPORT ("ixNpeDlLoadedImageFunctionalityGet "
921                                "- invalid parameter\n");
922         return IX_NPEDL_PARAM_ERR;
923     }
924     if (functionalityId == NULL)
925     {
926         IX_NPEDL_ERROR_REPORT ("ixNpeDlLoadedImageFunctionalityGet "
927                                "- invalid parameter\n");
928         return IX_NPEDL_PARAM_ERR;
929     }
930
931     if (ixNpeDlNpeState[npeId].validImage)
932     {
933         *functionalityId = ixNpeDlNpeState[npeId].imageId.functionalityId;
934         return IX_SUCCESS;
935     }
936     else
937     {
938         return IX_FAIL;
939     }
940 }