1 /*
2  * fs.c - CC31xx/CC32xx Host Driver Implementation
3  *
4  * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/
5  *
6  *
7  *  Redistribution and use in source and binary forms, with or without
8  *  modification, are permitted provided that the following conditions
9  *  are met:
10  *
11  *    Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  *
14  *    Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the
17  *    distribution.
18  *
19  *    Neither the name of Texas Instruments Incorporated nor the names of
20  *    its contributors may be used to endorse or promote products derived
21  *    from this software without specific prior written permission.
22  *
23  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  *
35 */
36 
37 
38 /*****************************************************************************/
39 /* Include files                                                             */
40 /*****************************************************************************/
41 #include <ti/drivers/net/wifi/simplelink.h>
42 #include <ti/drivers/net/wifi/source/protocol.h>
43 #include <ti/drivers/net/wifi/source/driver.h>
44 
45 /*****************************************************************************/
46 /* Macro declarations                                                        */
47 /*****************************************************************************/
48 #define sl_min(a,b) (((a) < (b)) ? (a) : (b))
49 #define MAX_NVMEM_CHUNK_SIZE  1456 /*should be 16 bytes align, because of encryption data*/
50 
51 /*****************************************************************************/
52 /* Internal functions                                                        */
53 /*****************************************************************************/
54 
55 static _u16 _SlFsStrlen(const _u8 *buffer);
56 
57 static _u32 FsGetCreateFsMode(_u8 Mode, _u32 MaxSizeInBytes,_u32 AccessFlags);
58 
59 /*****************************************************************************/
60 /* _SlFsStrlen                                                                */
61 /*****************************************************************************/
_SlFsStrlen(const _u8 * buffer)62 static _u16 _SlFsStrlen(const _u8 *buffer)
63 {
64     _u16 len = 0;
65     if( buffer != NULL )
66     {
67       while(*buffer++) len++;
68     }
69     return len;
70 }
71 /*****************************************************************************/
72 /*  _SlFsGetCreateFsMode                                                       */
73 /*****************************************************************************/
74 
75 /* Convert the user flag to the file System flag */
76 #define FS_CONVERT_FLAGS( ModeAndMaxSize )  (((_u32)ModeAndMaxSize & SL_FS_OPEN_FLAGS_BIT_MASK)>>SL_NUM_OF_MAXSIZE_BIT)
77 
78 typedef enum
79 {
80     FS_MODE_OPEN_READ            = 0,
81     FS_MODE_OPEN_WRITE,
82     FS_MODE_OPEN_CREATE,
83     FS_MODE_OPEN_WRITE_CREATE_IF_NOT_EXIST
84 }FsFileOpenAccessType_e;
85 
86 #define FS_MODE_ACCESS_RESERVED_OFFSET                       (27)
87 #define FS_MODE_ACCESS_RESERVED_MASK                         (0x1F)
88 #define FS_MODE_ACCESS_FLAGS_OFFSET                          (16)
89 #define FS_MODE_ACCESS_FLAGS_MASK                            (0x7FF)
90 #define FS_MODE_ACCESS_OFFSET                                (12)
91 #define FS_MODE_ACCESS_MASK                                  (0xF)
92 #define FS_MODE_OPEN_SIZE_GRAN_OFFSET                        (8)
93 #define FS_MODE_OPEN_SIZE_GRAN_MASK                          (0xF)
94 #define FS_MODE_OPEN_SIZE_OFFSET                             (0)
95 #define FS_MODE_OPEN_SIZE_MASK                               (0xFF)
96 #define FS_MAX_MODE_SIZE                                     (0xFF)
97 
98 /* SizeGran is up to 4 bit , Size can be up to 8 bit */
99 #define FS_MODE(Access, SizeGran, Size,Flags)        (_u32)(((_u32)((Access) &FS_MODE_ACCESS_MASK)<<FS_MODE_ACCESS_OFFSET) |  \
100                                                             ((_u32)((SizeGran) &FS_MODE_OPEN_SIZE_GRAN_MASK)<<FS_MODE_OPEN_SIZE_GRAN_OFFSET) | \
101                                                             ((_u32)((Size) &FS_MODE_OPEN_SIZE_MASK)<<FS_MODE_OPEN_SIZE_OFFSET) | \
102                                                             ((_u32)((Flags) &FS_MODE_ACCESS_FLAGS_MASK)<<FS_MODE_ACCESS_FLAGS_OFFSET))
103 
104 
105 typedef enum
106 {
107     FS_MODE_SIZE_GRAN_256B    = 0,   /*  MAX_SIZE = 64K  */
108     FS_MODE_SIZE_GRAN_1KB,           /*  MAX_SIZE = 256K */
109     FS_MODE_SIZE_GRAN_4KB,           /*  MAX_SZIE = 1M   */
110     FS_MODE_SIZE_GRAN_16KB,          /*  MAX_SIZE = 4M   */
111     FS_MODE_SIZE_GRAN_64KB,          /*  MAX_SIZE = 16M  */
112     FS_MAX_MODE_SIZE_GRAN
113 }FsFileOpenMaxSizeGran_e;
114 
115 
FsGetCreateFsMode(_u8 Mode,_u32 MaxSizeInBytes,_u32 AccessFlags)116 static _u32 FsGetCreateFsMode(_u8 Mode, _u32 MaxSizeInBytes,_u32 AccessFlags)
117 {
118    _u32 granIdx = 0;
119    _u32 granNum = 0;
120    _u32 granTable[FS_MAX_MODE_SIZE_GRAN] = {256,1024,4096,16384,65536};
121 
122    for(granIdx= FS_MODE_SIZE_GRAN_256B ;granIdx< FS_MAX_MODE_SIZE_GRAN;granIdx++)
123    {
124        if( granTable[granIdx]*255 >= MaxSizeInBytes )
125             break;
126    }
127    granNum = MaxSizeInBytes/granTable[granIdx];
128    if( MaxSizeInBytes % granTable[granIdx] != 0 )
129          granNum++;
130 
131    return (_u32)FS_MODE( Mode, granIdx, granNum, AccessFlags );
132 
133 }
134 
135 /*****************************************************************************/
136 /* API functions                                                             */
137 /*****************************************************************************/
138 
139 /*****************************************************************************/
140 /*  sl_FsOpen                                                                */
141 /*****************************************************************************/
142 typedef union
143 {
144     SlFsOpenCommand_t     Cmd;
145     SlFsOpenResponse_t    Rsp;
146 }_SlFsOpenMsg_u;
147 
148 #if _SL_INCLUDE_FUNC(sl_FsOpen)
149 
150 static const _SlCmdCtrl_t _SlFsOpenCmdCtrl =
151 {
152     SL_OPCODE_NVMEM_FILEOPEN,
153     (_SlArgSize_t)sizeof(SlFsOpenCommand_t),
154     (_SlArgSize_t)sizeof(SlFsOpenResponse_t)
155 };
156 
sl_FsOpen(const _u8 * pFileName,const _u32 ModeAndMaxSize,_u32 * pToken)157 _i32 sl_FsOpen(const _u8 *pFileName,const _u32 ModeAndMaxSize, _u32 *pToken)
158 {
159 
160     _SlFsOpenMsg_u        Msg;
161     _SlCmdExt_t           CmdExt;
162     _i32                  FileHandle;
163     _u32                  MaxSizeInBytes;
164     _u32                  OpenMode;
165     _u8                   CreateMode;
166 
167     /* verify that this api is allowed. if not allowed then
168     ignore the API execution and return immediately with an error */
169     VERIFY_API_ALLOWED(SL_OPCODE_SILO_FS);
170 
171     _SlDrvMemZero(&CmdExt, (_u16)sizeof(_SlCmdExt_t));
172 
173     if ( _SlFsStrlen(pFileName) >= SL_FS_MAX_FILE_NAME_LENGTH )
174     {
175         return SL_ERROR_FS_WRONG_FILE_NAME;
176     }
177 
178     CmdExt.TxPayload1Len = (_u16)((_SlFsStrlen(pFileName)+4) & (~3)); /* add 4: 1 for NULL and the 3 for align */
179     CmdExt.pTxPayload1 = (_u8*)pFileName;
180 
181     OpenMode = ModeAndMaxSize & SL_FS_OPEN_MODE_BIT_MASK;
182 
183     /*convert from the interface flags to the device flags*/
184     if( OpenMode == SL_FS_READ )
185     {
186         Msg.Cmd.Mode = FS_MODE(FS_MODE_OPEN_READ, 0, 0, 0);
187     }
188     else if (( OpenMode == SL_FS_WRITE ) ||( OpenMode == SL_FS_OVERWRITE))
189     {
190         Msg.Cmd.Mode = FS_MODE(FS_MODE_OPEN_WRITE, 0, 0, FS_CONVERT_FLAGS ( ModeAndMaxSize));
191     }
192     /* one of the creation mode */
193     else if ( ( OpenMode == (SL_FS_CREATE | SL_FS_OVERWRITE )) || ( OpenMode == SL_FS_CREATE) ||(OpenMode == (SL_FS_CREATE | SL_FS_WRITE )))
194     {
195        /* test that the size is correct */
196        MaxSizeInBytes = (ModeAndMaxSize & SL_FS_OPEN_MAXSIZE_BIT_MASK) * 256;
197        if (MaxSizeInBytes > 0xFF0000 )
198        {
199            return SL_ERROR_FS_FILE_MAX_SIZE_EXCEEDED;
200        }
201 
202        CreateMode = ((OpenMode == (SL_FS_CREATE | SL_FS_OVERWRITE )) ? FS_MODE_OPEN_WRITE_CREATE_IF_NOT_EXIST : FS_MODE_OPEN_CREATE  );
203 
204         Msg.Cmd.Mode = FsGetCreateFsMode( CreateMode ,MaxSizeInBytes, FS_CONVERT_FLAGS ( ModeAndMaxSize)  );
205     }
206     else
207     {
208         return SL_ERROR_FS_INVALID_FILE_MODE;
209     }
210 
211     if(pToken != NULL)
212     {
213         Msg.Cmd.Token         = *pToken;
214     }
215     else
216     {
217         Msg.Cmd.Token         = 0;
218     }
219 
220     _SlDrvCmdOp((_SlCmdCtrl_t *)&_SlFsOpenCmdCtrl, &Msg, &CmdExt);
221     FileHandle = (_i32)Msg.Rsp.FileHandle;
222     if (pToken != NULL)
223     {
224         *pToken =      Msg.Rsp.Token;
225     }
226 
227     /* in case of an error, return the erros file handler as an error code */
228     return FileHandle;
229 }
230 #endif
231 
232 /*****************************************************************************/
233 /* sl_FsClose */
234 /*****************************************************************************/
235 typedef union
236 {
237     SlFsCloseCommand_t    Cmd;
238     _BasicResponse_t        Rsp;
239 }_SlFsCloseMsg_u;
240 
241 #if _SL_INCLUDE_FUNC(sl_FsClose)
242 
243 static const _SlCmdCtrl_t _SlFsCloseCmdCtrl =
244 {
245     SL_OPCODE_NVMEM_FILECLOSE,
246     (_SlArgSize_t)sizeof(SlFsCloseCommand_t),
247     (_SlArgSize_t)sizeof(SlFsCloseResponse_t)
248 };
249 
sl_FsClose(const _i32 FileHdl,const _u8 * pCeritificateFileName,const _u8 * pSignature,const _u32 SignatureLen)250 _i16 sl_FsClose(const _i32 FileHdl, const _u8*  pCeritificateFileName,const _u8*  pSignature ,const _u32 SignatureLen)
251 {
252     _SlFsCloseMsg_u    Msg;
253     _SlCmdExt_t        ExtCtrl;
254 
255     _SlDrvMemZero(&Msg, (_u16)sizeof(SlFsCloseCommand_t));
256 
257     /* verify that this api is allowed. if not allowed then
258     ignore the API execution and return immediately with an error */
259     VERIFY_API_ALLOWED(SL_OPCODE_SILO_FS);
260 
261     Msg.Cmd.FileHandle             = (_u32)FileHdl;
262     if( pCeritificateFileName != NULL )
263     {
264         Msg.Cmd.CertificFileNameLength = (_u32)((_SlFsStrlen(pCeritificateFileName)+4) & (~3)); /* add 4: 1 for NULL and the 3 for align */
265     }
266     Msg.Cmd.SignatureLen           = SignatureLen;
267 
268     _SlDrvMemZero(&ExtCtrl, (_u16)sizeof(_SlCmdExt_t));
269 
270     ExtCtrl.TxPayload1Len = (_u16)(((SignatureLen+3) & (~3))); /* align */
271     ExtCtrl.pTxPayload1   = (_u8*)pSignature;
272     ExtCtrl.RxPayloadLen  = (_i16)Msg.Cmd.CertificFileNameLength;
273     ExtCtrl.pRxPayload    = (_u8*)pCeritificateFileName; /* Add signature */
274 
275     if(ExtCtrl.pRxPayload != NULL &&  ExtCtrl.RxPayloadLen != 0)
276     {
277        ExtCtrl.RxPayloadLen = ExtCtrl.RxPayloadLen * (-1);
278     }
279 
280     VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlFsCloseCmdCtrl, &Msg, &ExtCtrl));
281 
282     return (_i16)((_i16)Msg.Rsp.status);
283 }
284 #endif
285 
286 
287 /*****************************************************************************/
288 /* sl_FsRead */
289 /*****************************************************************************/
290 typedef union
291 {
292     SlFsReadCommand_t        Cmd;
293     SlFsReadResponse_t    Rsp;
294 }_SlFsReadMsg_u;
295 
296 #if _SL_INCLUDE_FUNC(sl_FsRead)
297 
298 static const _SlCmdCtrl_t _SlFsReadCmdCtrl =
299 {
300     SL_OPCODE_NVMEM_FILEREADCOMMAND,
301     (_SlArgSize_t)sizeof(SlFsReadCommand_t),
302     (_SlArgSize_t)sizeof(SlFsReadResponse_t)
303 };
304 
sl_FsRead(const _i32 FileHdl,_u32 Offset,_u8 * pData,_u32 Len)305 _i32 sl_FsRead(const _i32 FileHdl,_u32 Offset, _u8*  pData,_u32 Len)
306 {
307     _SlFsReadMsg_u      Msg;
308     _SlCmdExt_t         ExtCtrl;
309     _u16                ChunkLen;
310     _SlReturnVal_t      RetVal =0;
311     _i32                RetCount = 0;
312 
313     /* verify that this api is allowed. if not allowed then
314     ignore the API execution and return immediately with an error */
315     VERIFY_API_ALLOWED(SL_OPCODE_SILO_FS);
316 
317     _SlDrvMemZero(&ExtCtrl, (_u16)sizeof(_SlCmdExt_t));
318 
319     ChunkLen             = (_u16)sl_min(MAX_NVMEM_CHUNK_SIZE,Len);
320     ExtCtrl.RxPayloadLen = (_i16)ChunkLen;
321     ExtCtrl.pRxPayload   = (_u8 *)(pData);
322     Msg.Cmd.Offset       = Offset;
323     Msg.Cmd.Len          = ChunkLen;
324     Msg.Cmd.FileHandle   = (_u32)FileHdl;
325     do
326     {
327         RetVal = _SlDrvCmdOp((_SlCmdCtrl_t *)&_SlFsReadCmdCtrl, &Msg, &ExtCtrl);
328         if(SL_OS_RET_CODE_OK == RetVal)
329         {
330             if( Msg.Rsp.status < 0)
331             {
332                 if( RetCount > 0)
333                 {
334                    return RetCount;
335                 }
336                 else
337                 {
338                    return Msg.Rsp.status;
339                 }
340             }
341             RetCount += (_i32)Msg.Rsp.status;
342             Len -= ChunkLen;
343             Offset += ChunkLen;
344             Msg.Cmd.Offset = Offset;
345             ExtCtrl.pRxPayload += ChunkLen;
346             ChunkLen = (_u16)sl_min(MAX_NVMEM_CHUNK_SIZE,Len);
347             ExtCtrl.RxPayloadLen  = (_i16)ChunkLen;
348             Msg.Cmd.Len = ChunkLen;
349             Msg.Cmd.FileHandle = (_u32)FileHdl;
350         }
351         else
352         {
353             return RetVal;
354         }
355     }while(ChunkLen > 0);
356 
357     return (_i32)RetCount;
358 }
359 #endif
360 
361 /*****************************************************************************/
362 /* sl_FsWrite */
363 /*****************************************************************************/
364 typedef union
365 {
366     SlFsWriteCommand_t        Cmd;
367     SlFsWriteResponse_t        Rsp;
368 }_SlFsWriteMsg_u;
369 
370 #if _SL_INCLUDE_FUNC(sl_FsWrite)
371 
372 static const _SlCmdCtrl_t _SlFsWriteCmdCtrl =
373 {
374     SL_OPCODE_NVMEM_FILEWRITECOMMAND,
375     (_SlArgSize_t)sizeof(SlFsWriteCommand_t),
376     (_SlArgSize_t)sizeof(SlFsWriteResponse_t)
377 };
378 
sl_FsWrite(const _i32 FileHdl,_u32 Offset,_u8 * pData,_u32 Len)379 _i32 sl_FsWrite(const _i32 FileHdl,_u32 Offset, _u8*  pData,_u32 Len)
380 {
381     _SlFsWriteMsg_u     Msg;
382     _SlCmdExt_t         ExtCtrl;
383     _u16                ChunkLen;
384     _SlReturnVal_t      RetVal;
385     _i32                RetCount = 0;
386 
387     /* verify that this api is allowed. if not allowed then
388     ignore the API execution and return immediately with an error */
389     VERIFY_API_ALLOWED(SL_OPCODE_SILO_FS);
390 
391     _SlDrvMemZero(&ExtCtrl, (_u16)sizeof(_SlCmdExt_t));
392 
393     ChunkLen              = (_u16)sl_min(MAX_NVMEM_CHUNK_SIZE,Len);
394     ExtCtrl.TxPayload1Len = ChunkLen;
395     ExtCtrl.pTxPayload1   = (_u8 *)(pData);
396     Msg.Cmd.Offset        = Offset;
397     Msg.Cmd.Len           = ChunkLen;
398     Msg.Cmd.FileHandle    = (_u32)FileHdl;
399 
400     do
401     {
402         RetVal = _SlDrvCmdOp((_SlCmdCtrl_t *)&_SlFsWriteCmdCtrl, &Msg, &ExtCtrl);
403         if(SL_OS_RET_CODE_OK == RetVal)
404         {
405             if( Msg.Rsp.status < 0)
406             {
407                 if( RetCount > 0)
408                 {
409                     return RetCount;
410                 }
411                 else
412                 {
413                     return Msg.Rsp.status;
414                 }
415             }
416 
417             RetCount += (_i32)Msg.Rsp.status;
418             Len -= ChunkLen;
419             Offset += ChunkLen;
420             Msg.Cmd.Offset = Offset;
421             ExtCtrl.pTxPayload1 += ChunkLen;
422             ChunkLen = (_u16)sl_min(MAX_NVMEM_CHUNK_SIZE,Len);
423             ExtCtrl.TxPayload1Len  = ChunkLen;
424             Msg.Cmd.Len = ChunkLen;
425             Msg.Cmd.FileHandle = (_u32)FileHdl;
426         }
427         else
428         {
429             return RetVal;
430         }
431     }while(ChunkLen > 0);
432 
433     return (_i32)RetCount;
434 }
435 #endif
436 
437 /*****************************************************************************/
438 /* sl_FsGetInfo */
439 /*****************************************************************************/
440 typedef union
441 {
442     SlFsGetInfoCommand_t        Cmd;
443     SlFsGetInfoResponse_t    Rsp;
444 }_SlFsGetInfoMsg_u;
445 
446 #if _SL_INCLUDE_FUNC(sl_FsGetInfo)
447 
448 static const _SlCmdCtrl_t _SlFsGetInfoCmdCtrl =
449 {
450     SL_OPCODE_NVMEM_FILEGETINFOCOMMAND,
451     (_SlArgSize_t)sizeof(SlFsGetInfoCommand_t),
452     (_SlArgSize_t)sizeof(SlFsGetInfoResponse_t)
453 };
454 
455 const _u16 FlagsTranslate[] =
456 {
457     SL_FS_INFO_OPEN_WRITE,
458     SL_FS_INFO_OPEN_READ,
459     SL_FS_INFO_NOT_FAILSAFE,
460     SL_FS_INFO_NOT_VALID,
461     SL_FS_INFO_SYS_FILE,
462     SL_FS_INFO_MUST_COMMIT,
463     SL_FS_INFO_BUNDLE_FILE,
464     SL_FS_INFO_PENDING_COMMIT,
465     SL_FS_INFO_PENDING_BUNDLE_COMMIT,
466     0,
467     SL_FS_INFO_SECURE,
468     SL_FS_INFO_NOSIGNATURE,
469     SL_FS_INFO_PUBLIC_WRITE,
470     SL_FS_INFO_PUBLIC_READ,
471     0,
472     0
473 };
474 
sl_FsGetInfo(const _u8 * pFileName,const _u32 Token,SlFsFileInfo_t * pFsFileInfo)475 _i16 sl_FsGetInfo(const _u8 *pFileName,const _u32 Token,SlFsFileInfo_t* pFsFileInfo)
476 {
477     _SlFsGetInfoMsg_u    Msg;
478     _SlCmdExt_t          CmdExt;
479     _u16                 BitNum;
480 
481     /* verify that this api is allowed. if not allowed then
482     ignore the API execution and return immediately with an error */
483     VERIFY_API_ALLOWED(SL_OPCODE_SILO_FS);
484 
485     _SlDrvMemZero(&CmdExt, (_u16)sizeof(_SlCmdExt_t));
486 
487     if ( _SlFsStrlen(pFileName) >= SL_FS_MAX_FILE_NAME_LENGTH )
488     {
489         return SL_ERROR_FS_WRONG_FILE_NAME;
490     }
491 
492     CmdExt.TxPayload1Len = (_u16)((_SlFsStrlen(pFileName)+4) & (~3)); /* add 4: 1 for NULL and the 3 for align  */
493     CmdExt.pTxPayload1   = (_u8*)pFileName;
494 
495     Msg.Cmd.Token        = Token;
496 
497     VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlFsGetInfoCmdCtrl, &Msg, &CmdExt));
498 
499     /* convert flags */
500     pFsFileInfo->Flags = 0;
501     for (BitNum = 0; BitNum < 16; BitNum++ )
502     {
503         if (( Msg.Rsp.Flags >> BitNum) & 0x1 )
504         {
505             pFsFileInfo->Flags |= FlagsTranslate[BitNum];
506         }
507     }
508 
509     pFsFileInfo->Len          = Msg.Rsp.FileLen;
510     pFsFileInfo->MaxSize      = Msg.Rsp.AllocatedLen;
511     pFsFileInfo->Token[0]     = Msg.Rsp.Token[0];
512     pFsFileInfo->Token[1]     = Msg.Rsp.Token[1];
513     pFsFileInfo->Token[2]     = Msg.Rsp.Token[2];
514     pFsFileInfo->Token[3]     = Msg.Rsp.Token[3];
515     pFsFileInfo->StorageSize  = Msg.Rsp.FileStorageSize;
516     pFsFileInfo->WriteCounter = Msg.Rsp.FileWriteCounter;
517 
518     return  (_i16)((_i16)Msg.Rsp.Status);
519 }
520 #endif
521 
522 /*****************************************************************************/
523 /* sl_FsDel */
524 /*****************************************************************************/
525 typedef union
526 {
527     SlFsDeleteCommand_t           Cmd;
528     SlFsDeleteResponse_t          Rsp;
529 }_SlFsDeleteMsg_u;
530 
531 
532 #if _SL_INCLUDE_FUNC(sl_FsDel)
533 
534 static const _SlCmdCtrl_t _SlFsDeleteCmdCtrl =
535 {
536     SL_OPCODE_NVMEM_FILEDELCOMMAND,
537     (_SlArgSize_t)sizeof(SlFsDeleteCommand_t),
538     (_SlArgSize_t)sizeof(SlFsDeleteResponse_t)
539 };
540 
sl_FsDel(const _u8 * pFileName,const _u32 Token)541 _i16 sl_FsDel(const _u8 *pFileName,const _u32 Token)
542 {
543     _SlFsDeleteMsg_u Msg;
544     _SlCmdExt_t      CmdExt;
545 
546     /* verify that this api is allowed. if not allowed then
547     ignore the API execution and return immediately with an error */
548     VERIFY_API_ALLOWED(SL_OPCODE_SILO_FS);
549 
550     if ( _SlFsStrlen(pFileName) >= SL_FS_MAX_FILE_NAME_LENGTH )
551     {
552         return SL_ERROR_FS_WRONG_FILE_NAME;
553     }
554 
555     _SlDrvMemZero(&CmdExt, (_u16)sizeof(_SlCmdExt_t));
556 
557     CmdExt.TxPayload1Len = (_u16)((_SlFsStrlen(pFileName)+4) & (~3)); /* add 4: 1 for NULL and the 3 for align */
558     CmdExt.pTxPayload1   = (_u8*)pFileName;
559     Msg.Cmd.Token        = Token;
560 
561     VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlFsDeleteCmdCtrl, &Msg, &CmdExt));
562 
563     return  (_i16)((_i16)Msg.Rsp.status);
564 }
565 #endif
566 
567 /*****************************************************************************/
568 /* sl_FsCtl */
569 /*****************************************************************************/
570 typedef union
571 {
572   SlFsFileSysControlCommand_t        Cmd;
573   SlFsFileSysControlResponse_t       Rsp;
574 }_SlFsFileSysControlMsg_u;
575 
576 #if _SL_INCLUDE_FUNC(sl_FsCtl)
577 
578 const _SlCmdCtrl_t _SlFsFileSysControlCmdCtrl =
579 {
580     SL_OPCODE_NVMEM_NVMEMFILESYSTEMCONTROLCOMMAND,
581     sizeof(SlFsFileSysControlCommand_t),
582     sizeof(SlFsFileSysControlResponse_t)
583 };
584 
sl_FsCtl(SlFsCtl_e Command,_u32 Token,_u8 * pFileName,const _u8 * pData,_u16 DataLen,_u8 * pOutputData,_u16 OutputDataLen,_u32 * pNewToken)585 _i32 sl_FsCtl( SlFsCtl_e Command, _u32 Token,   _u8 *pFileName, const _u8 *pData, _u16 DataLen, _u8 *pOutputData, _u16 OutputDataLen,_u32 *pNewToken )
586 {
587     _SlFsFileSysControlMsg_u     Msg;
588     _SlCmdExt_t                  CmdExt;
589 
590     /* verify that this api is allowed. if not allowed then
591     ignore the API execution and return immediately with an error */
592     VERIFY_API_ALLOWED(SL_OPCODE_SILO_FS);
593 
594     Msg.Cmd.Token = Token;
595     Msg.Cmd.Operation = (_u8)Command;
596 
597     _SlDrvMemZero(&CmdExt, (_u16)sizeof(_SlCmdExt_t));
598 
599     if ((SL_FS_CTL_ROLLBACK == Command) || (SL_FS_CTL_COMMIT == Command ))
600     {
601         Msg.Cmd.FileNameLength = _SlFsStrlen(pFileName) + 1 ;
602 
603         if ( _SlFsStrlen(pFileName) >= SL_FS_MAX_FILE_NAME_LENGTH )
604         {
605             return SL_ERROR_FS_WRONG_FILE_NAME;
606         }
607 
608         /*the data is aligned*/
609         CmdExt.RxPayloadLen = DataLen;
610         CmdExt.pRxPayload = (_u8 *)(pData);
611 
612         CmdExt.TxPayload1Len = (_SlFsStrlen(pFileName) + 4) & (~3);
613         CmdExt.pTxPayload1   = pFileName;
614 
615         Msg.Cmd.BufferLength =  CmdExt.RxPayloadLen + CmdExt.TxPayload1Len;
616 
617        if(CmdExt.pRxPayload != NULL &&  CmdExt.RxPayloadLen != 0)
618        {
619            CmdExt.RxPayloadLen = CmdExt.RxPayloadLen * (-1);
620        }
621     }
622     else if( SL_FS_CTL_RENAME == Command )
623     {
624         if ( _SlFsStrlen(pFileName) >= SL_FS_MAX_FILE_NAME_LENGTH )
625         {
626             return SL_ERROR_FS_WRONG_FILE_NAME;
627         }
628 
629         Msg.Cmd.FileNameLength = (_SlFsStrlen(pFileName) + 4) & (~3);
630 
631         /*current file name*/
632         CmdExt.RxPayloadLen = (_u16)Msg.Cmd.FileNameLength;
633         CmdExt.pRxPayload   = pFileName;
634 
635         /*New file name*/
636         CmdExt.TxPayload1Len = (_SlFsStrlen(pData) + 4) & (~3);;
637         CmdExt.pTxPayload1 = (_u8 *)(pData);
638 
639         Msg.Cmd.BufferLength =  CmdExt.RxPayloadLen + CmdExt.TxPayload1Len;
640 
641        if(CmdExt.pRxPayload != NULL &&  CmdExt.RxPayloadLen != 0)
642        {
643            CmdExt.RxPayloadLen = CmdExt.RxPayloadLen * (-1);
644        }
645     }
646     else
647     {
648         Msg.Cmd.FileNameLength = 0;
649 
650         CmdExt.TxPayload1Len = (DataLen + 3) & (~3);
651         CmdExt.pTxPayload1 = (_u8 *)(pData);
652 
653         CmdExt.RxPayloadLen = OutputDataLen;
654         CmdExt.pRxPayload = pOutputData;
655 
656         Msg.Cmd.BufferLength =  CmdExt.TxPayload1Len;
657     }
658 
659     VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlFsFileSysControlCmdCtrl, &Msg, &CmdExt));
660 
661     if( pNewToken != NULL )
662     {
663         *pNewToken = Msg.Rsp.Token;
664     }
665 
666     return  (_i32)((_i32)Msg.Rsp.Status);
667 }
668 #endif
669 
670 
671 /*****************************************************************************/
672 /* sl_FsProgram */
673 /*****************************************************************************/
674 typedef union
675 {
676     SlFsProgramCommand_t        Cmd;
677     SlFsProgramResponse_t       Rsp;
678 }_SlFsProgrammingMsg_u;
679 
680 #if _SL_INCLUDE_FUNC(sl_FsProgram)
681 
682 const _SlCmdCtrl_t _SlFsProgrammingCmdCtrl =
683 {
684     SL_OPCODE_NVMEM_NVMEMFSPROGRAMMINGCOMMAND,
685     sizeof(SlFsProgramCommand_t),
686     sizeof(SlFsProgramResponse_t)
687 };
688 
sl_FsProgram(const _u8 * pData,_u16 DataLen,const _u8 * pKey,_u32 Flags)689 _i32   sl_FsProgram(const _u8*  pData , _u16 DataLen ,const _u8 * pKey ,  _u32 Flags )
690 {
691     _SlFsProgrammingMsg_u     Msg;
692     _SlCmdExt_t               CmdExt;
693     _u16                      ChunkLen;
694 
695     VERIFY_API_ALLOWED(SL_OPCODE_SILO_FS);
696 
697     Msg.Cmd.Flags = (_u32)Flags;
698 
699    _SlDrvResetCmdExt(&CmdExt);
700 
701     /* no data and no key, called only for extracting the image */
702     if( (DataLen == 0) && (pKey == NULL) )
703     {
704         Msg.Cmd.ChunkLen = 0;
705         Msg.Cmd.KeyLen = 0;
706         Msg.Cmd.Flags = Flags;
707         VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlFsProgrammingCmdCtrl, &Msg, &CmdExt));
708     }
709     else if( (DataLen> 0)  && ( pData == NULL))
710     {
711        return (SL_ERROR_FS_WRONG_INPUT_SIZE_INTERNAL_SHIFTED_16_LEFT);
712     }
713     else if( (DataLen == 0) && (pKey != NULL) )
714     {
715         Msg.Cmd.ChunkLen = 0;
716         Msg.Cmd.KeyLen = sizeof(SlFsKey_t);;
717         Msg.Cmd.Flags = Flags;
718         CmdExt.pTxPayload1 = (_u8*)pKey;
719         CmdExt.TxPayload1Len  = sizeof(SlFsKey_t);
720         VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlFsProgrammingCmdCtrl, &Msg, &CmdExt));
721     }
722     else /* DataLen > 0 */
723     {
724         if( (DataLen & 0xF) > 0)
725         {
726             return (SL_ERROR_FS_NOT_16_ALIGNED_INTERNAL_SHIFTED_16_LEFT);
727         }
728         Msg.Cmd.Flags = Flags;
729 
730         CmdExt.pTxPayload1 = (_u8 *)pData;
731         ChunkLen = (_u16)sl_min(MAX_NVMEM_CHUNK_SIZE, DataLen);
732 
733         while(ChunkLen > 0)
734         {
735             Msg.Cmd.ChunkLen  = ChunkLen;
736             CmdExt.TxPayload1Len = ChunkLen;
737             if( pKey != NULL )
738             {
739                 Msg.Cmd.KeyLen = sizeof(SlFsKey_t);
740                 CmdExt.RxPayloadLen = sizeof(SlFsKey_t);
741                 CmdExt.pRxPayload = (_u8 *)pKey;
742 
743                 if(CmdExt.pRxPayload != NULL &&  CmdExt.RxPayloadLen != 0)
744                 {
745                     CmdExt.RxPayloadLen = CmdExt.RxPayloadLen * (-1);
746                 }
747             }
748             else /* No key */
749             {
750                 Msg.Cmd.KeyLen = 0;
751                 CmdExt.RxPayloadLen = 0;
752                 CmdExt.pRxPayload   = NULL;
753             }
754 
755             VERIFY_RET_OK( _SlDrvCmdOp((_SlCmdCtrl_t *)&_SlFsProgrammingCmdCtrl, &Msg, &CmdExt));
756 
757             if( Msg.Rsp.Status <= 0 ) /* Error or finished */
758             {
759                 return (_i32)(Msg.Rsp.Status);
760             }
761 
762             DataLen -= ChunkLen;
763             CmdExt.pTxPayload1 += ChunkLen;
764 
765             ChunkLen = (_u16)sl_min(MAX_NVMEM_CHUNK_SIZE, DataLen);
766         }
767     }
768 
769     return  (_i32)(Msg.Rsp.Status);
770 }
771 #endif
772 
773 /*****************************************************************************/
774 /* sl_FsGetFileList */
775 /*****************************************************************************/
776 typedef union
777 {
778     SlFsGetFileListCommand_t        Cmd;
779     SlFsGetFileListResponse_t        Rsp;
780 }_SlFsGetFileListMsg_u;
781 
782 #if _SL_INCLUDE_FUNC(sl_FsGetFileList)
783 
784 const _SlCmdCtrl_t _SlFsGetFileListCmdCtrl =
785 {
786     SL_OPCODE_NVMEM_NVMEMGETFILELISTCOMMAND,
787     sizeof(SlFsGetFileListCommand_t),
788     sizeof(SlFsGetFileListResponse_t)
789 };
790 
sl_FsGetFileList(_i32 * pIndex,_u8 Count,_u8 MaxEntryLen,_u8 * pBuff,SlFileListFlags_t Flags)791 _i32  sl_FsGetFileList(_i32* pIndex, _u8 Count, _u8 MaxEntryLen , _u8* pBuff, SlFileListFlags_t Flags )
792 {
793     _SlFsGetFileListMsg_u     Msg;
794     _SlCmdExt_t               CmdExt;
795     _u16                      OutputBufferSize;
796 
797     /* verify that this api is allowed. if not allowed then
798     ignore the API execution and return immediately with an error */
799     VERIFY_API_ALLOWED(SL_OPCODE_SILO_FS);
800 
801     _SlDrvResetCmdExt(&CmdExt);
802 
803     Msg.Cmd.Index = *pIndex;
804     Msg.Cmd.MaxEntryLen = MaxEntryLen  & (~3); /* round to modulu 4 */
805     Msg.Cmd.Count = Count;
806     Msg.Cmd.Flags = (_u8)Flags;
807 
808     OutputBufferSize = Msg.Cmd.Count * Msg.Cmd.MaxEntryLen;
809     if( OutputBufferSize > MAX_NVMEM_CHUNK_SIZE )
810     {
811         return SL_ERROR_FS_WRONG_INPUT_SIZE;
812     }
813 
814     CmdExt.RxPayloadLen = OutputBufferSize;
815     CmdExt.pRxPayload   = pBuff;
816 
817     VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlFsGetFileListCmdCtrl, &Msg, &CmdExt));
818 
819     *pIndex = Msg.Rsp.Index;
820 
821     return  (_i32)((_i32)Msg.Rsp.NumOfEntriesOrError);
822 }
823 #endif
824 
825