Merge branch 'mpc86xx'
[platform/kernel/u-boot.git] / 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: ixNpeDlMicrocodeImageLibraryOverride
113  */
114 PUBLIC IX_STATUS
115 ixNpeDlMicrocodeImageLibraryOverride (UINT32 *clientImageLibrary)
116 {
117     IX_STATUS status = IX_SUCCESS;
118
119     IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
120                      "Entering ixNpeDlMicrocodeImageLibraryOverride\n");
121
122     if (clientImageLibrary == NULL)
123     {
124         status = IX_NPEDL_PARAM_ERR;
125         IX_NPEDL_ERROR_REPORT ("ixNpeDlMicrocodeImageLibraryOverride - "
126                                "invalid parameter\n");
127     }
128     else
129     {
130         status = ixNpeDlImageMgrMicrocodeImageLibraryOverride (clientImageLibrary);
131         if (status != IX_SUCCESS)
132         {
133             status = IX_FAIL;
134         }
135     } /* end of if-else(clientImageLibrary) */
136
137     IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
138                      "Exiting ixNpeDlMicrocodeImageLibraryOverride : "
139                      "status = %d\n", status);
140     return status;
141 }
142
143 /*
144  * Function definition: ixNpeDlImageDownload
145  */
146 PUBLIC IX_STATUS
147 ixNpeDlImageDownload (IxNpeDlImageId *imageIdPtr,
148                       BOOL verify)
149 {
150     UINT32        imageSize;
151     UINT32       *imageCodePtr  = NULL;
152     IX_STATUS     status;
153     IxNpeDlNpeId  npeId           = imageIdPtr->npeId;
154
155     IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
156                      "Entering ixNpeDlImageDownload\n");
157
158     ixNpeDlStats.attemptedDownloads++;
159
160     /* Check input parameters */
161     if ((npeId >= IX_NPEDL_NPEID_MAX) || (npeId < 0))
162     {
163         status = IX_NPEDL_PARAM_ERR;
164         IX_NPEDL_ERROR_REPORT ("ixNpeDlImageDownload - invalid parameter\n");
165     }
166     else
167     {
168         /* Ensure initialisation has been completed */
169         ixNpeDlNpeMgrInit();
170
171         /* If not IXP42X A0 stepping, proceed to check for existence of npe's */
172         if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
173              (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
174             || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
175         {
176             if (npeId == IX_NPEDL_NPEID_NPEA)
177             {
178                 if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA) ==
179                     IX_FEATURE_CTRL_COMPONENT_DISABLED)
180                 {
181                     IX_NPEDL_WARNING_REPORT("Warning: the NPE A component you specified does"
182                                             " not exist\n");
183                     return IX_SUCCESS;
184                 }
185             } /* end of if(npeId) */
186             else if (npeId == IX_NPEDL_NPEID_NPEB)
187             {
188                 if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB)==
189                     IX_FEATURE_CTRL_COMPONENT_DISABLED)
190                 {
191                     IX_NPEDL_WARNING_REPORT("Warning: the NPE B component you specified"
192                                             " does not exist\n");
193                     return IX_SUCCESS;
194                 }
195             } /* end of elseif(npeId) */
196             else if (npeId == IX_NPEDL_NPEID_NPEC)
197             {
198                 if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC)==
199                     IX_FEATURE_CTRL_COMPONENT_DISABLED)
200                 {
201                     IX_NPEDL_WARNING_REPORT("Warning: the NPE C component you specified"
202                                             " does not exist\n");
203                     return IX_SUCCESS;
204                 }
205             } /* end of elseif(npeId) */
206         } /* end of if(IX_FEATURE_CTRL_SILICON_TYPE_B0) */ /*End of Silicon Type Check*/
207
208         /* stop and reset the NPE */
209         if (IX_SUCCESS != ixNpeDlNpeStopAndReset (npeId))
210         {
211             IX_NPEDL_ERROR_REPORT ("Failed to stop and reset NPE\n");
212             return IX_FAIL;
213         }
214
215         /* Locate image */
216         status = ixNpeDlImageMgrImageLocate (imageIdPtr, &imageCodePtr,
217                                              &imageSize);
218         if (IX_SUCCESS == status)
219         {
220             /*
221              * If download was successful, store image Id in list of
222              * currently loaded images. If a critical error occured
223              * during download, record that the NPE has an invalid image
224              */
225             status = ixNpeDlNpeMgrImageLoad (npeId, imageCodePtr,
226                                              verify);
227             if (IX_SUCCESS == status)
228             {
229                 ixNpeDlNpeState[npeId].imageId = *imageIdPtr;
230                 ixNpeDlNpeState[npeId].validImage = TRUE;
231                 ixNpeDlStats.successfulDownloads++;
232
233                 status =  ixNpeDlNpeExecutionStart (npeId);
234             }
235             else if ((status == IX_NPEDL_CRITICAL_NPE_ERR) ||
236                      (status == IX_NPEDL_CRITICAL_MICROCODE_ERR))
237             {
238                 ixNpeDlNpeState[npeId].imageId = *imageIdPtr;
239                 ixNpeDlNpeState[npeId].validImage = FALSE;
240                 ixNpeDlStats.criticalFailDownloads++;
241             }
242         } /* end of if(IX_SUCCESS) */ /* condition: image located successfully in microcode image */
243     } /* end of if-else(npeId) */ /* condition: parameter checks ok */
244
245     IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
246                      "Exiting ixNpeDlImageDownload : status = %d\n", status);
247     return status;
248 }
249
250 /*
251  * Function definition: ixNpeDlAvailableImagesCountGet
252  */
253 PUBLIC IX_STATUS
254 ixNpeDlAvailableImagesCountGet (UINT32 *numImagesPtr)
255 {
256     IX_STATUS status;
257
258     IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
259                      "Entering ixNpeDlAvailableImagesCountGet\n");
260
261     /* Check input parameters */
262     if (numImagesPtr == NULL)
263     {
264         status = IX_NPEDL_PARAM_ERR;
265         IX_NPEDL_ERROR_REPORT ("ixNpeDlAvailableImagesCountGet - "
266                                "invalid parameter\n");
267     }
268     else
269     {
270         /*
271          * Use ImageMgr module to get no. of images listed in Image Library Header.
272          * If NULL is passed as imageListPtr parameter to following function,
273          * it will only fill number of images into numImagesPtr
274          */
275         status = ixNpeDlImageMgrImageListExtract (NULL, numImagesPtr);
276     } /* end of if-else(numImagesPtr) */
277
278     IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
279                      "Exiting ixNpeDlAvailableImagesCountGet : "
280                      "status = %d\n", status);
281     return status;
282 }
283
284 /*
285  * Function definition: ixNpeDlAvailableImagesListGet
286  */
287 PUBLIC IX_STATUS
288 ixNpeDlAvailableImagesListGet (IxNpeDlImageId *imageIdListPtr,
289                                UINT32 *listSizePtr)
290 {
291     IX_STATUS status;
292
293     IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
294                      "Entering ixNpeDlAvailableImagesListGet\n");
295
296     /* Check input parameters */
297     if ((imageIdListPtr == NULL) || (listSizePtr == NULL))
298     {
299         status = IX_NPEDL_PARAM_ERR;
300         IX_NPEDL_ERROR_REPORT ("ixNpeDlAvailableImagesListGet - "
301                                "invalid parameter\n");
302     }
303     else
304     {
305         /* Call ImageMgr to get list of images listed in Image Library Header */
306         status = ixNpeDlImageMgrImageListExtract (imageIdListPtr,
307                                                   listSizePtr);
308     } /* end of if-else(imageIdListPtr) */
309
310     IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
311                      "Exiting ixNpeDlAvailableImagesListGet : status = %d\n",
312                      status);
313     return status;
314 }
315
316 /*
317  * Function definition: ixNpeDlLoadedImageGet
318  */
319 PUBLIC IX_STATUS
320 ixNpeDlLoadedImageGet (IxNpeDlNpeId npeId,
321                        IxNpeDlImageId *imageIdPtr)
322 {
323     IX_STATUS status = IX_SUCCESS;
324
325     IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
326                      "Entering ixNpeDlLoadedImageGet\n");
327
328     /* Check input parameters */
329     if ((npeId >= IX_NPEDL_NPEID_MAX) || (npeId < 0) || (imageIdPtr == NULL))
330     {
331         status = IX_NPEDL_PARAM_ERR;
332         IX_NPEDL_ERROR_REPORT ("ixNpeDlLoadedImageGet - invalid parameter\n");
333     }
334     else
335     {
336
337          /* If not IXP42X A0 stepping, proceed to check for existence of npe's */
338          if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
339               (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
340              || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
341         {
342             if (npeId == IX_NPEDL_NPEID_NPEA &&
343                 (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA) ==
344                  IX_FEATURE_CTRL_COMPONENT_DISABLED))
345             {
346                 IX_NPEDL_WARNING_REPORT("Warning: the NPE A component you specified does"
347                                         " not exist\n");
348                 return IX_SUCCESS;
349             } /* end of if(npeId) */
350
351             if (npeId == IX_NPEDL_NPEID_NPEB &&
352                 (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB) ==
353                  IX_FEATURE_CTRL_COMPONENT_DISABLED))
354             {
355                 IX_NPEDL_WARNING_REPORT("Warning: the NPE B component you specified does"
356                                         " not exist\n");
357                 return IX_SUCCESS;
358             } /* end of if(npeId) */
359
360             if (npeId == IX_NPEDL_NPEID_NPEC &&
361                 (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC) ==
362                  IX_FEATURE_CTRL_COMPONENT_DISABLED))
363             {
364                 IX_NPEDL_WARNING_REPORT("Warning: the NPE C component you specified does"
365                                         " not exist\n");
366                 return IX_SUCCESS;
367             } /* end of if(npeId) */
368         } /* end of if not IXP42x-A0 silicon */
369
370         if (ixNpeDlNpeState[npeId].validImage)
371         {
372             /* use npeId to get imageId from list of currently loaded
373                images */
374             *imageIdPtr = ixNpeDlNpeState[npeId].imageId;
375         }
376         else
377         {
378             status = IX_FAIL;
379         } /* end of if-else(ixNpeDlNpeState) */
380     } /* end of if-else(npeId) */
381
382     IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
383                      "Exiting ixNpeDlLoadedImageGet : status = %d\n",
384                      status);
385     return status;
386 }
387
388 /*
389  * Function definition: ixNpeDlLatestImageGet
390  */
391 PUBLIC IX_STATUS
392 ixNpeDlLatestImageGet (
393     IxNpeDlNpeId npeId,
394     IxNpeDlFunctionalityId functionalityId,
395     IxNpeDlImageId *imageIdPtr)
396 {
397     IX_STATUS status;
398
399     IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
400                      "Entering ixNpeDlLatestImageGet\n");
401
402     /* Check input parameters */
403     if ((npeId >= IX_NPEDL_NPEID_MAX) ||
404         (npeId < 0) ||
405         (imageIdPtr == NULL))
406     {
407         status = IX_NPEDL_PARAM_ERR;
408         IX_NPEDL_ERROR_REPORT ("ixNpeDlLatestImageGet - "
409                                "invalid parameter\n");
410     } /* end of if(npeId) */
411     else
412     {
413
414         /* If not IXP42X A0 stepping, proceed to check for existence of npe's */
415         if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
416              (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
417             || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
418         {
419             if (npeId == IX_NPEDL_NPEID_NPEA &&
420                 (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA) ==
421                  IX_FEATURE_CTRL_COMPONENT_DISABLED))
422             {
423                 IX_NPEDL_WARNING_REPORT("Warning: the NPE A component you specified does"
424                                         " not exist\n");
425                 return IX_SUCCESS;
426             } /* end of if(npeId) */
427
428             if (npeId == IX_NPEDL_NPEID_NPEB &&
429                 (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB) ==
430                  IX_FEATURE_CTRL_COMPONENT_DISABLED))
431             {
432                 IX_NPEDL_WARNING_REPORT("Warning: the NPE B component you specified does"
433                                         " not exist\n");
434                 return IX_SUCCESS;
435             } /* end of if(npeId) */
436
437             if (npeId == IX_NPEDL_NPEID_NPEC &&
438                 (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC) ==
439                  IX_FEATURE_CTRL_COMPONENT_DISABLED))
440             {
441                 IX_NPEDL_WARNING_REPORT("Warning: the NPE C component you specified does"
442                                         " not exist\n");
443                 return IX_SUCCESS;
444             } /* end of if(npeId) */
445         } /* end of if not IXP42x-A0 silicon */
446
447         imageIdPtr->npeId = npeId;
448         imageIdPtr->functionalityId = functionalityId;
449         imageIdPtr->major = IMAGEID_MAJOR_NUMBER_DEFAULT;
450         imageIdPtr->minor = IMAGEID_MINOR_NUMBER_DEFAULT;
451         /* Call ImageMgr to get list of images listed in Image Library Header */
452         status = ixNpeDlImageMgrLatestImageExtract(imageIdPtr);
453     } /* end of if-else(npeId) */
454
455     IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
456                      "Exiting ixNpeDlLatestImageGet : status = %d\n",
457                      status);
458
459     return status;
460 }
461
462 /*
463  * Function definition: ixNpeDlNpeStopAndReset
464  */
465 PUBLIC IX_STATUS
466 ixNpeDlNpeStopAndReset (IxNpeDlNpeId npeId)
467 {
468     IX_STATUS status = IX_SUCCESS;
469
470     IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
471                      "Entering ixNpeDlNpeStopAndReset\n");
472
473     /* Ensure initialisation has been completed */
474     ixNpeDlNpeMgrInit();
475
476     /* If not IXP42X A0 stepping, proceed to check for existence of npe's */
477     if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
478          (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
479         || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
480     {
481         /*
482          * Check whether NPE is present
483          */
484         if (IX_NPEDL_NPEID_NPEA == npeId)
485         {
486             /* Check whether NPE A is present */
487             if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA)==
488                 IX_FEATURE_CTRL_COMPONENT_DISABLED)
489             {
490                 /* NPE A does not present */
491                 IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeStopAndReset - Warning:NPEA does not present.\n");
492                 return IX_SUCCESS;
493             }
494         } /* end of if(IX_NPEDL_NPEID_NPEA) */
495         else if (IX_NPEDL_NPEID_NPEB == npeId)
496         {
497             /* Check whether NPE B is present */
498             if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB)==
499                 IX_FEATURE_CTRL_COMPONENT_DISABLED)
500             {
501                 /* NPE B does not present */
502                 IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeStopAndReset - Warning:NPEB does not present.\n");
503                 return IX_SUCCESS;
504             }
505         } /* end of elseif(IX_NPEDL_NPEID_NPEB) */
506         else if (IX_NPEDL_NPEID_NPEC == npeId)
507         {
508             /* Check whether NPE C is present */
509             if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC)==
510                 IX_FEATURE_CTRL_COMPONENT_DISABLED)
511             {
512                 /* NPE C does not present */
513                 IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeStopAndReset - Warning:NPEC does not present.\n");
514                 return IX_SUCCESS;
515             }
516         } /* end of elseif(IX_NPEDL_NPEID_NPEC) */
517         else
518         {
519             /* Invalid NPE ID */
520             IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeStopAndReset - invalid Npe ID\n");
521             status = IX_NPEDL_PARAM_ERR;
522         } /* end of if-else(IX_NPEDL_NPEID_NPEC) */
523     } /* end of if not IXP42x-A0 Silicon */
524
525     if (status == IX_SUCCESS)
526     {
527         /* call NpeMgr function to stop the NPE */
528         status = ixNpeDlNpeMgrNpeStop (npeId);
529         if (status == IX_SUCCESS)
530         {
531             /* call NpeMgr function to reset the NPE */
532             status = ixNpeDlNpeMgrNpeReset (npeId);
533         }
534     } /* end of if(status) */
535
536     IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
537                      "Exiting ixNpeDlNpeStopAndReset : status = %d\n", status);
538
539     if (IX_SUCCESS == status)
540     {
541         /* Indicate NPE has been stopped */
542         ixNpeDlNpeStarted[npeId] = FALSE ;
543     }
544
545     return status;
546 }
547
548 /*
549  * Function definition: ixNpeDlNpeExecutionStart
550  */
551 PUBLIC IX_STATUS
552 ixNpeDlNpeExecutionStart (IxNpeDlNpeId npeId)
553 {
554     IX_STATUS status = IX_SUCCESS;
555
556     IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
557                      "Entering ixNpeDlNpeExecutionStart\n");
558
559     /* If not IXP42X A0 stepping, proceed to check for existence of npe's */
560     if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
561          (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
562         || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
563     {
564         /*
565          * Check whether NPE is present
566          */
567         if (IX_NPEDL_NPEID_NPEA == npeId)
568         {
569             /* Check whether NPE A is present */
570             if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA)==
571                 IX_FEATURE_CTRL_COMPONENT_DISABLED)
572             {
573                 /* NPE A does not present */
574                 IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStart - Warning:NPEA does not present.\n");
575                 return IX_SUCCESS;
576             }
577         } /* end of if(IX_NPEDL_NPEID_NPEA) */
578         else if (IX_NPEDL_NPEID_NPEB == npeId)
579         {
580             /* Check whether NPE B is present */
581             if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB)==
582                 IX_FEATURE_CTRL_COMPONENT_DISABLED)
583             {
584                 /* NPE B does not present */
585                 IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStart - Warning:NPEB does not present.\n");
586                 return IX_SUCCESS;
587             }
588         } /* end of elseif(IX_NPEDL_NPEID_NPEB) */
589         else if (IX_NPEDL_NPEID_NPEC ==  npeId)
590         {
591             /* Check whether NPE C is present */
592             if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC)==
593                 IX_FEATURE_CTRL_COMPONENT_DISABLED)
594             {
595                 /* NPE C does not present */
596                 IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStart - Warning:NPEC does not present.\n");
597                 return IX_SUCCESS;
598             }
599         } /* end of elseif(IX_NPEDL_NPEID_NPEC) */
600         else
601         {
602             /* Invalid NPE ID */
603             IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeExecutionStart - invalid Npe ID\n");
604             return IX_NPEDL_PARAM_ERR;
605         } /* end of if-else(IX_NPEDL_NPEID_NPEC) */
606     } /* end of if not IXP42x-A0 Silicon */
607
608     if (TRUE == ixNpeDlNpeStarted[npeId])
609     {
610         /* NPE has been started. */
611         return IX_SUCCESS ;
612     }
613
614     /* Ensure initialisation has been completed */
615     ixNpeDlNpeMgrInit();
616
617     /* call NpeMgr function to start the NPE */
618     status = ixNpeDlNpeMgrNpeStart (npeId);
619
620     if (IX_SUCCESS == status)
621     {
622         /* Indicate NPE has started */
623         ixNpeDlNpeStarted[npeId] = TRUE ;
624     }
625
626     IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
627                      "Exiting ixNpeDlNpeExecutionStart : status = %d\n",
628                      status);
629
630     return status;
631 }
632
633 /*
634  * Function definition: ixNpeDlNpeExecutionStop
635  */
636 PUBLIC IX_STATUS
637 ixNpeDlNpeExecutionStop (IxNpeDlNpeId npeId)
638 {
639     IX_STATUS status = IX_SUCCESS;
640
641     IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
642                      "Entering ixNpeDlNpeExecutionStop\n");
643
644     /* Ensure initialisation has been completed */
645     ixNpeDlNpeMgrInit();
646
647     /* If not IXP42X A0 stepping, proceed to check for existence of npe's */
648     if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
649          (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
650         || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
651     {
652         /*
653          * Check whether NPE is present
654          */
655         if (IX_NPEDL_NPEID_NPEA == npeId)
656         {
657             /* Check whether NPE A is present */
658             if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA)==
659                 IX_FEATURE_CTRL_COMPONENT_DISABLED)
660             {
661                 /* NPE A does not present */
662                 IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStop - Warning:NPEA does not present.\n");
663                 return IX_SUCCESS;
664             }
665         } /* end of if(IX_NPEDL_NPEID_NPEA) */
666         else if (IX_NPEDL_NPEID_NPEB == npeId)
667         {
668             /* Check whether NPE B is present */
669             if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB)==
670                 IX_FEATURE_CTRL_COMPONENT_DISABLED)
671             {
672                 /* NPE B does not present */
673                 IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStop - Warning:NPEB does not present.\n");
674                 return IX_SUCCESS;
675             }
676         } /* end of elseif(IX_NPEDL_NPEID_NPEB) */
677         else if (IX_NPEDL_NPEID_NPEC == npeId)
678         {
679             /* Check whether NPE C is present */
680             if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC)==
681                 IX_FEATURE_CTRL_COMPONENT_DISABLED)
682             {
683                 /* NPE C does not present */
684                 IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStop - Warning:NPEC does not present.\n");
685                 return IX_SUCCESS;
686             }
687         } /* end of elseif(IX_NPEDL_NPEID_NPEC) */
688         else
689         {
690             /* Invalid NPE ID */
691             IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeExecutionStop - invalid Npe ID\n");
692             status = IX_NPEDL_PARAM_ERR;
693         } /* end of if-else(IX_NPEDL_NPEID_NPEC) */
694     } /* end of if not IXP42X-AO Silicon */
695
696     if (status == IX_SUCCESS)
697     {
698         /* call NpeMgr function to stop the NPE */
699         status = ixNpeDlNpeMgrNpeStop (npeId);
700     }
701
702     IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
703                      "Exiting ixNpeDlNpeExecutionStop : status = %d\n",
704                      status);
705
706     if (IX_SUCCESS == status)
707     {
708         /* Indicate NPE has been stopped */
709         ixNpeDlNpeStarted[npeId] = FALSE ;
710     }
711
712     return status;
713 }
714
715 /*
716  * Function definition: ixNpeDlUnload
717  */
718 PUBLIC IX_STATUS
719 ixNpeDlUnload (void)
720 {
721     IX_STATUS status;
722
723     IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
724                      "Entering ixNpeDlUnload\n");
725
726     status = ixNpeDlNpeMgrUninit();
727
728     IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
729                      "Exiting ixNpeDlUnload : status = %d\n",
730                      status);
731     return status;
732 }
733
734 /*
735  * Function definition: ixNpeDlStatsShow
736  */
737 PUBLIC void
738 ixNpeDlStatsShow (void)
739 {
740     ixOsalLog (IX_OSAL_LOG_LVL_USER,
741                IX_OSAL_LOG_DEV_STDOUT,
742                "\nixNpeDlStatsShow:\n"
743                "\tDownloads Attempted by user: %u\n"
744                "\tSuccessful Downloads: %u\n"
745                "\tFailed Downloads (due to Critical Error): %u\n\n",
746                ixNpeDlStats.attemptedDownloads,
747                ixNpeDlStats.successfulDownloads,
748                ixNpeDlStats.criticalFailDownloads,
749                0,0,0);
750
751     ixNpeDlImageMgrStatsShow ();
752     ixNpeDlNpeMgrStatsShow ();
753 }
754
755 /*
756  * Function definition: ixNpeDlStatsReset
757  */
758 PUBLIC void
759 ixNpeDlStatsReset (void)
760 {
761     ixNpeDlStats.attemptedDownloads = 0;
762     ixNpeDlStats.successfulDownloads = 0;
763     ixNpeDlStats.criticalFailDownloads = 0;
764
765     ixNpeDlImageMgrStatsReset ();
766     ixNpeDlNpeMgrStatsReset ();
767 }
768
769 /*
770  * Function definition: ixNpeDlNpeInitAndStartInternal
771  */
772 PRIVATE IX_STATUS
773 ixNpeDlNpeInitAndStartInternal (UINT32 *imageLibrary,
774                                 UINT32 imageId)
775 {
776     UINT32        imageSize;
777     UINT32       *imageCodePtr  = NULL;
778     IX_STATUS     status;
779     IxNpeDlNpeId  npeId = IX_NPEDL_NPEID_FROM_IMAGEID_GET(imageId);
780     IxFeatureCtrlDeviceId deviceId = IX_NPEDL_DEVICEID_FROM_IMAGEID_GET(imageId);
781
782     IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
783                      "Entering ixNpeDlNpeInitAndStartInternal\n");
784
785     ixNpeDlStats.attemptedDownloads++;
786
787     /* Check input parameter device correctness */
788     if ((deviceId >= IX_FEATURE_CTRL_DEVICE_TYPE_MAX) ||
789         (deviceId < IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X))
790     {
791         status = IX_NPEDL_PARAM_ERR;
792         IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeInitAndStartInternal - "
793                                "invalid parameter\n");
794     } /* End valid device id checking */
795
796     /* Check input parameters */
797     else if ((npeId >= IX_NPEDL_NPEID_MAX) || (npeId < 0))
798     {
799         status = IX_NPEDL_PARAM_ERR;
800         IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeInitAndStartInternal - "
801                                "invalid parameter\n");
802     }
803
804     else
805     {
806         /* Ensure initialisation has been completed */
807         ixNpeDlNpeMgrInit();
808
809         /* Checking if image being loaded is meant for device that is running.
810          * Image is forward compatible. i.e Image built for IXP42X should run
811          * on IXP46X but not vice versa.*/
812         if (deviceId > (ixFeatureCtrlDeviceRead() & IX_FEATURE_CTRL_DEVICE_TYPE_MASK))
813         {
814             IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeInitAndStartInternal - "
815                                    "Device type mismatch. NPE Image not "
816                                    "meant for device in use \n");
817             return IX_NPEDL_DEVICE_ERR;
818         }/* if statement - matching image device and current device */
819
820         /* If not IXP42X A0 stepping, proceed to check for existence of npe's */
821         if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
822              (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
823             || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
824         {
825             if (npeId == IX_NPEDL_NPEID_NPEA)
826             {
827                 if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA) ==
828                     IX_FEATURE_CTRL_COMPONENT_DISABLED)
829                 {
830                     IX_NPEDL_WARNING_REPORT("Warning: the NPE A component you specified does"
831                                             " not exist\n");
832                     return IX_SUCCESS;
833                 }
834             } /* end of if(npeId) */
835             else if (npeId == IX_NPEDL_NPEID_NPEB)
836             {
837                 if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB)==
838                     IX_FEATURE_CTRL_COMPONENT_DISABLED)
839                 {
840                     IX_NPEDL_WARNING_REPORT("Warning: the NPE B component you specified"
841                                             " does not exist\n");
842                     return IX_SUCCESS;
843                 }
844             } /* end of elseif(npeId) */
845             else if (npeId == IX_NPEDL_NPEID_NPEC)
846             {
847                 if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC)==
848                     IX_FEATURE_CTRL_COMPONENT_DISABLED)
849                 {
850                     IX_NPEDL_WARNING_REPORT("Warning: the NPE C component you specified"
851                                             " does not exist\n");
852                     return IX_SUCCESS;
853                 }
854             } /* end of elseif(npeId) */
855         } /* end of if not IXP42X-A0 Silicon */
856
857         /* stop and reset the NPE */
858         status = ixNpeDlNpeStopAndReset (npeId);
859         if (IX_SUCCESS != status)
860         {
861             IX_NPEDL_ERROR_REPORT ("Failed to stop and reset NPE\n");
862             return status;
863         }
864
865         /* Locate image */
866         status = ixNpeDlImageMgrImageFind (imageLibrary, imageId,
867                                            &imageCodePtr, &imageSize);
868         if (IX_SUCCESS == status)
869         {
870             /*
871              * If download was successful, store image Id in list of
872              * currently loaded images. If a critical error occured
873              * during download, record that the NPE has an invalid image
874              */
875             status = ixNpeDlNpeMgrImageLoad (npeId, imageCodePtr, TRUE);
876             if (IX_SUCCESS == status)
877             {
878                 ixNpeDlNpeState[npeId].validImage = TRUE;
879                 ixNpeDlStats.successfulDownloads++;
880
881                 status = ixNpeDlNpeExecutionStart (npeId);
882             }
883             else if ((status == IX_NPEDL_CRITICAL_NPE_ERR) ||
884                      (status == IX_NPEDL_CRITICAL_MICROCODE_ERR))
885             {
886                 ixNpeDlNpeState[npeId].validImage = FALSE;
887                 ixNpeDlStats.criticalFailDownloads++;
888             }
889
890             /* NOTE - The following section of code is here to support
891              * a deprecated function ixNpeDlLoadedImageGet().  When that
892              * function is removed from the API, this code should be revised.
893              */
894             ixNpeDlNpeState[npeId].imageId.npeId = npeId;
895             ixNpeDlNpeState[npeId].imageId.functionalityId =
896                 IX_NPEDL_FUNCTIONID_FROM_IMAGEID_GET(imageId);
897             ixNpeDlNpeState[npeId].imageId.major =
898                 IX_NPEDL_MAJOR_FROM_IMAGEID_GET(imageId);
899             ixNpeDlNpeState[npeId].imageId.minor =
900                 IX_NPEDL_MINOR_FROM_IMAGEID_GET(imageId);
901         } /* end of if(IX_SUCCESS) */ /* condition: image located successfully in microcode image */
902     } /* end of if-else(npeId-deviceId) */ /* condition: parameter checks ok */
903
904     IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
905                      "Exiting ixNpeDlNpeInitAndStartInternal : "
906                      "status = %d\n", status);
907     return status;
908 }
909
910 /*
911  * Function definition: ixNpeDlCustomImageNpeInitAndStart
912  */
913 PUBLIC IX_STATUS
914 ixNpeDlCustomImageNpeInitAndStart (UINT32 *imageLibrary,
915                                    UINT32 imageId)
916 {
917     IX_STATUS status;
918
919     if (imageLibrary == NULL)
920     {
921         status = IX_NPEDL_PARAM_ERR;
922         IX_NPEDL_ERROR_REPORT ("ixNpeDlCustomImageNpeInitAndStart "
923                                "- invalid parameter\n");
924     }
925     else
926     {
927         status = ixNpeDlNpeInitAndStartInternal (imageLibrary, imageId);
928     } /* end of if-else(imageLibrary) */
929
930     return status;
931 }
932
933 /*
934  * Function definition: ixNpeDlNpeInitAndStart
935  */
936 PUBLIC IX_STATUS
937 ixNpeDlNpeInitAndStart (UINT32 imageId)
938 {
939     return ixNpeDlNpeInitAndStartInternal (NULL, imageId);
940 }
941
942 /*
943  * Function definition: ixNpeDlLoadedImageFunctionalityGet
944  */
945 PUBLIC IX_STATUS
946 ixNpeDlLoadedImageFunctionalityGet (IxNpeDlNpeId npeId,
947                                     UINT8 *functionalityId)
948 {
949     /* Check input parameters */
950     if ((npeId >= IX_NPEDL_NPEID_MAX) || (npeId < 0))
951     {
952         IX_NPEDL_ERROR_REPORT ("ixNpeDlLoadedImageFunctionalityGet "
953                                "- invalid parameter\n");
954         return IX_NPEDL_PARAM_ERR;
955     }
956     if (functionalityId == NULL)
957     {
958         IX_NPEDL_ERROR_REPORT ("ixNpeDlLoadedImageFunctionalityGet "
959                                "- invalid parameter\n");
960         return IX_NPEDL_PARAM_ERR;
961     }
962
963     if (ixNpeDlNpeState[npeId].validImage)
964     {
965         *functionalityId = ixNpeDlNpeState[npeId].imageId.functionalityId;
966         return IX_SUCCESS;
967     }
968     else
969     {
970         return IX_FAIL;
971     }
972 }