1 /*
2 * device.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 /* Include files */
39 /*****************************************************************************/
40 #include <ti/drivers/net/wifi/simplelink.h>
41 #include <ti/drivers/net/wifi/source/protocol.h>
42 #include <ti/drivers/net/wifi/source/driver.h>
43 #include <ti/drivers/net/wifi/source/flowcont.h>
44
45 /*****************************************************************************/
46 /* Internal functions */
47 /*****************************************************************************/
48
49 static _i16 _SlDeviceGetStartResponseConvert(_i32 Status);
50 void _SlDeviceHandleResetRequestInternally(void);
51 void _SlDeviceResetRequestInitCompletedCB(_u32 Status, SlDeviceInitInfo_t *DeviceInitInfo);
52
53 #define RESET_REQUEST_STOP_TIMEOUT (300)
54
55 #ifndef SL_IF_OPEN_FLAGS
56 #define SL_IF_OPEN_FLAGS (0x0)
57 #endif
58
59 #ifndef SL_IF_UART_REOPEN_FLAGS
60 #define SL_IF_UART_REOPEN_FLAGS (0x1)
61 #endif
62
63 typedef struct
64 {
65 const void *pIfHdl; /* Holds the last opened interface handle */
66 _i8 *pDevName; /* Holds the last opened interface parameters */
67 _u32 ResetRequestSessionNumber; /* Special session number to be verified upon every reset request during provisioning */
68 } _SlDeviceCb_t;
69
70 _SlDeviceCb_t DeviceCB; /* the device control block */
71
72 static const _i16 StartResponseLUT[16] =
73 {
74 ROLE_RESERVED,
75 ROLE_STA,
76 SL_ERROR_ROLE_STA_ERR,
77 ROLE_AP,
78 SL_ERROR_ROLE_AP_ERR,
79 ROLE_P2P,
80 SL_ERROR_ROLE_P2P_ERR,
81 SL_ERROR_CALIB_FAIL,
82 SL_ERROR_FS_CORRUPTED_ERR,
83 SL_ERROR_FS_ALERT_ERR,
84 SL_ERROR_RESTORE_IMAGE_COMPLETE,
85 SL_ERROR_INCOMPLETE_PROGRAMMING,
86 ROLE_TAG,
87 SL_ERROR_ROLE_TAG_ERR,
88 SL_ERROR_FIPS_ERR,
89 SL_ERROR_GENERAL_ERR
90 };
91
_SlDeviceGetStartResponseConvert(_i32 Status)92 static _i16 _SlDeviceGetStartResponseConvert(_i32 Status)
93 {
94 return StartResponseLUT[Status & 0xF];
95 }
96
97 /*****************************************************************************/
98 /* API Functions */
99 /*****************************************************************************/
100
101 /*****************************************************************************/
102 /* sl_Task */
103 /*****************************************************************************/
104 #if _SL_INCLUDE_FUNC(sl_Task)
sl_Task(void * pEntry)105 void* sl_Task(void* pEntry)
106 {
107 #ifdef _SlTaskEntry
108 return (void*)_SlTaskEntry();
109 #else
110 return (void*)0;
111 #endif
112 }
113 #endif
114
115 /*****************************************************************************/
116 /* sl_Start */
117 /*****************************************************************************/
118 #if _SL_INCLUDE_FUNC(sl_Start)
sl_Start(const void * pIfHdl,_i8 * pDevName,const P_INIT_CALLBACK pInitCallBack)119 _i16 sl_Start(const void* pIfHdl, _i8* pDevName, const P_INIT_CALLBACK pInitCallBack)
120 {
121 _i16 ObjIdx = MAX_CONCURRENT_ACTIONS;
122 InitComplete_t AsyncRsp;
123 int ret = 0; // added for releasePoolObj
124
125 _SlDrvMemZero(&AsyncRsp, sizeof(InitComplete_t));
126
127 /* verify no error handling in progress. if in progress than
128 ignore the API execution and return immediately with an error */
129 VERIFY_NO_ERROR_HANDLING_IN_PROGRESS();
130 if (SL_IS_DEVICE_STARTED)
131 {
132 return SL_RET_CODE_DEV_ALREADY_STARTED;
133 }
134 /* Perform any preprocessing before enable networking services */
135 #ifdef sl_DeviceEnablePreamble
136 sl_DeviceEnablePreamble();
137 #endif
138
139 /* ControlBlock init */
140 (void)_SlDrvDriverCBInit();
141
142 /* open the interface: usually SPI or UART */
143 if (NULL == pIfHdl)
144 {
145 g_pCB->FD = sl_IfOpen((void *)pDevName, SL_IF_OPEN_FLAGS);
146 }
147 else
148 {
149 g_pCB->FD = (_SlFd_t)pIfHdl;
150 }
151
152 ObjIdx = _SlDrvProtectAsyncRespSetting((_u8 *)&AsyncRsp, START_STOP_ID, SL_MAX_SOCKETS);
153
154 if (ObjIdx < 0)
155 {
156 return ObjIdx;
157 }
158
159 if( g_pCB->FD >= (_SlFd_t)0)
160 {
161 /* store the interface parameters for the internal call of the
162 sl_start to be called upon reset request handling */
163 DeviceCB.pIfHdl = pIfHdl;
164 DeviceCB.pDevName = pDevName;
165
166 /* Mark that device is in progress! */
167 SL_SET_DEVICE_START_IN_PROGRESS;
168
169 sl_DeviceDisable();
170
171 sl_IfRegIntHdlr((SL_P_EVENT_HANDLER)_SlDrvRxIrqHandler, NULL);
172
173 g_pCB->pInitCallback = pInitCallBack;
174 sl_DeviceEnable();
175
176 if (NULL == pInitCallBack)
177 {
178 ret = _SlDrvWaitForInternalAsyncEvent(ObjIdx, INIT_COMPLETE_TIMEOUT, SL_OPCODE_DEVICE_INITCOMPLETE);
179
180 SL_UNSET_DEVICE_START_IN_PROGRESS;
181
182 SL_SET_DEVICE_STARTED;
183
184 /* release Pool Object */
185 _SlDrvReleasePoolObj(g_pCB->FunctionParams.AsyncExt.ActionIndex);
186 if(ret < 0)
187 {
188 return ret;
189 }
190 else
191 {
192 return _SlDeviceGetStartResponseConvert(AsyncRsp.Status);
193 }
194 }
195 else
196 {
197 return SL_RET_CODE_OK;
198 }
199 }
200 return SL_BAD_INTERFACE;
201 }
202 #endif
203
204 /***************************************************************************
205 _SlDeviceHandleAsync_InitComplete - handles init complete signalling to
206 a waiting object
207 ****************************************************************************/
_SlDeviceHandleAsync_InitComplete(void * pVoidBuf)208 _SlReturnVal_t _SlDeviceHandleAsync_InitComplete(void *pVoidBuf)
209 {
210 InitComplete_t *pMsgArgs = (InitComplete_t *)_SL_RESP_ARGS_START(pVoidBuf);
211 SlDeviceInitInfo_t DeviceInitInfo;
212
213 SL_DRV_PROTECTION_OBJ_LOCK_FOREVER();
214
215 if(g_pCB->pInitCallback)
216 {
217 DeviceInitInfo.ChipId = pMsgArgs->ChipId;
218 DeviceInitInfo.MoreData = pMsgArgs->MoreData;
219 g_pCB->pInitCallback(_SlDeviceGetStartResponseConvert(pMsgArgs->Status), &DeviceInitInfo);
220 }
221 else
222 {
223 sl_Memcpy(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs, pMsgArgs, sizeof(InitComplete_t));
224 SL_DRV_SYNC_OBJ_SIGNAL(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj);
225 }
226
227 SL_DRV_PROTECTION_OBJ_UNLOCK();
228 if(g_pCB->pInitCallback)
229 {
230 SL_SET_DEVICE_STARTED;
231 SL_UNSET_DEVICE_START_IN_PROGRESS;
232 _SlDrvReleasePoolObj(g_pCB->FunctionParams.AsyncExt.ActionIndex);
233 }
234
235 return SL_OS_RET_CODE_OK;
236 }
237
238
239 /***************************************************************************
240 _SlDeviceHandleAsync_Stop - handles stop signalling to
241 a waiting object
242 ****************************************************************************/
_SlDeviceHandleAsync_Stop(void * pVoidBuf)243 void _SlDeviceHandleAsync_Stop(void *pVoidBuf)
244 {
245 _BasicResponse_t *pMsgArgs = (_BasicResponse_t *)_SL_RESP_ARGS_START(pVoidBuf);
246
247 VERIFY_SOCKET_CB(NULL != g_pCB->StopCB.pAsyncRsp);
248
249 SL_DRV_PROTECTION_OBJ_LOCK_FOREVER();
250
251 if (g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs != NULL)
252 {
253 sl_Memcpy(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs, pMsgArgs, sizeof(_BasicResponse_t));
254 SL_DRV_SYNC_OBJ_SIGNAL(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj);
255 }
256
257 SL_DRV_PROTECTION_OBJ_UNLOCK();
258
259 return;
260 }
261
262
263 /*****************************************************************************
264 sl_stop
265 ******************************************************************************/
266 typedef union
267 {
268 SlDeviceStopCommand_t Cmd;
269 _BasicResponse_t Rsp;
270 }_SlStopMsg_u;
271
272 static const _SlCmdCtrl_t _SlStopCmdCtrl =
273 {
274 SL_OPCODE_DEVICE_STOP_COMMAND,
275 (_SlArgSize_t)sizeof(SlDeviceStopCommand_t),
276 (_SlArgSize_t)sizeof(_BasicResponse_t)
277 };
278
279 #if _SL_INCLUDE_FUNC(sl_Stop)
sl_Stop(const _u16 Timeout)280 _i16 sl_Stop(const _u16 Timeout)
281 {
282 _i16 RetVal=0;
283 _SlStopMsg_u Msg;
284 _BasicResponse_t AsyncRsp;
285 _i16 ObjIdx = MAX_CONCURRENT_ACTIONS;
286 _u8 ReleasePoolObject = FALSE;
287 _u8 IsProvInProgress = FALSE;
288
289 /* NOTE: don't check VERIFY_API_ALLOWED(), this command is not
290 * filtered in error handling and also not filtered in NWP lock state.
291 * If we are in the middle of assert handling than ignore stopping
292 * the device with timeout and force immediate shutdown as we would like
293 * to avoid any additional commands to the NWP */
294 if( (Timeout != 0) && (SL_IS_DEVICE_STARTED)
295 && (!SL_IS_RESTART_REQUIRED))
296 {
297 /* Clear the Async response structure */
298 _SlDrvMemZero(&AsyncRsp, sizeof(_BasicResponse_t));
299
300 /* let the device make the shutdown using the defined timeout */
301 Msg.Cmd.Timeout = Timeout;
302
303 IsProvInProgress = SL_IS_PROVISIONING_IN_PROGRESS;
304
305 /* if provisioning in progress do not take pool object as we are not going to wait for it */
306 if (!IsProvInProgress)
307 {
308 ObjIdx = _SlDrvProtectAsyncRespSetting((_u8 *)&AsyncRsp, START_STOP_ID, SL_MAX_SOCKETS);
309 if (ObjIdx < 0)
310 {
311 return ObjIdx;
312 }
313
314 ReleasePoolObject = TRUE;
315 }
316
317 /* Set the stop-in-progress flag */
318 SL_SET_DEVICE_STOP_IN_PROGRESS;
319
320 VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlStopCmdCtrl, &Msg, NULL));
321
322 int ret_pool = 0; // for _SlDrvReleasePoolObj
323 /* Do not wait for stop async event if provisioning is in progress */
324 if((SL_OS_RET_CODE_OK == (_i16)Msg.Rsp.status) && (!(IsProvInProgress)))
325 {
326 /* Wait for sync object to be signaled */
327 ret_pool = _SlDrvWaitForInternalAsyncEvent(ObjIdx, STOP_DEVICE_TIMEOUT, SL_OPCODE_DEVICE_STOP_ASYNC_RESPONSE);
328
329 Msg.Rsp.status = AsyncRsp.status;
330 RetVal = Msg.Rsp.status;
331 }
332
333 /* Release pool object only if taken */
334 if (ReleasePoolObject == TRUE)
335 {
336 _SlDrvReleasePoolObj(ObjIdx);
337 if(ret_pool < 0)
338 {
339 return ret_pool;
340 }
341 }
342
343 /* This macro wait for the NWP to raise a ready for shutdown indication.
344 * This function is unique for the CC32XX family, and expected to return
345 * in less than 600 mSec, which is the time takes for NWP to gracefully shutdown. */
346 WAIT_NWP_SHUTDOWN_READY;
347 }
348 else
349 {
350 if ((!SL_IS_DEVICE_STARTED)
351 && (!SL_IS_RESTART_REQUIRED))
352 {
353 sl_DeviceDisable();
354 return SL_RET_CODE_DEV_NOT_STARTED;
355 }
356 /* Set the stop-in-progress flag */
357 SL_SET_DEVICE_STOP_IN_PROGRESS;
358 }
359 /* Release (signal) all active and pending commands */
360 _SlDrvReleaseAllActivePendingPoolObj();
361
362 #ifdef SL_PLATFORM_MULTI_THREADED
363 /* Do not continue until all sync object deleted (in relevant context) */
364 while (g_pCB->NumOfDeletedSyncObj < MAX_CONCURRENT_ACTIONS)
365 {
366 usleep(100000);
367 }
368 #endif
369
370 /* Lock during stopping the interface */
371 SL_DRV_OBJ_LOCK_FOREVER(&GlobalLockObj);
372
373 sl_IfRegIntHdlr(NULL, NULL);
374 sl_DeviceDisable();
375 RetVal = sl_IfClose(g_pCB->FD);
376
377 (void)_SlDrvDriverCBDeinit();
378
379 /* clear the stop-in-progress flag */
380 SL_UNSET_DEVICE_STOP_IN_PROGRESS;
381
382 /* clear the device started flag */
383 SL_UNSET_DEVICE_STARTED;
384
385 SL_DRV_OBJ_UNLOCK(&GlobalLockObj);
386
387 return RetVal;
388 }
389 #endif
390
391
392 /*****************************************************************************
393 sl_DeviceEventMaskSet
394 *****************************************************************************/
395 typedef union
396 {
397 SlDeviceMaskEventSetCommand_t Cmd;
398 _BasicResponse_t Rsp;
399 }_SlEventMaskSetMsg_u;
400
401
402 #if _SL_INCLUDE_FUNC(sl_DeviceEventMaskSet)
403
404 static const _SlCmdCtrl_t _SlEventMaskSetCmdCtrl =
405 {
406 SL_OPCODE_DEVICE_EVENTMASKSET,
407 (_SlArgSize_t)sizeof(SlDeviceMaskEventSetCommand_t),
408 (_SlArgSize_t)sizeof(_BasicResponse_t)
409 };
410
411
sl_DeviceEventMaskSet(const _u8 EventClass,const _u32 Mask)412 _i16 sl_DeviceEventMaskSet(const _u8 EventClass ,const _u32 Mask)
413 {
414 _SlEventMaskSetMsg_u Msg;
415
416 /* verify that this api is allowed. if not allowed then
417 ignore the API execution and return immediately with an error */
418 VERIFY_API_ALLOWED(SL_OPCODE_SILO_DEVICE);
419
420 Msg.Cmd.Group = EventClass;
421 Msg.Cmd.Mask = Mask;
422
423 VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlEventMaskSetCmdCtrl, &Msg, NULL));
424
425 return (_i16)Msg.Rsp.status;
426 }
427 #endif
428
429 /******************************************************************************
430 sl_EventMaskGet
431 ******************************************************************************/
432 typedef union
433 {
434 SlDeviceMaskEventGetCommand_t Cmd;
435 SlDeviceMaskEventGetResponse_t Rsp;
436 }_SlEventMaskGetMsg_u;
437
438
439
440 #if _SL_INCLUDE_FUNC(sl_DeviceEventMaskGet)
441
442 static const _SlCmdCtrl_t _SlEventMaskGetCmdCtrl =
443 {
444 SL_OPCODE_DEVICE_EVENTMASKGET,
445 (_SlArgSize_t)sizeof(SlDeviceMaskEventGetCommand_t),
446 (_SlArgSize_t)sizeof(SlDeviceMaskEventGetResponse_t)
447 };
448
449
sl_DeviceEventMaskGet(const _u8 EventClass,_u32 * pMask)450 _i16 sl_DeviceEventMaskGet(const _u8 EventClass,_u32 *pMask)
451 {
452 _SlEventMaskGetMsg_u Msg;
453
454 /* verify that this api is allowed. if not allowed then
455 ignore the API execution and return immediately with an error */
456 VERIFY_API_ALLOWED(SL_OPCODE_SILO_DEVICE);
457
458 Msg.Cmd.Group = EventClass;
459
460 VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlEventMaskGetCmdCtrl, &Msg, NULL));
461
462 *pMask = Msg.Rsp.Mask;
463
464 return SL_RET_CODE_OK;
465 }
466 #endif
467
468
469
470 /******************************************************************************
471 sl_DeviceGet
472 ******************************************************************************/
473
474 typedef union
475 {
476 SlDeviceSetGet_t Cmd;
477 SlDeviceSetGet_t Rsp;
478 }_SlDeviceMsgGet_u;
479
480
481
482 #if _SL_INCLUDE_FUNC(sl_DeviceGet)
483
484 static const _SlCmdCtrl_t _SlDeviceGetCmdCtrl =
485 {
486 SL_OPCODE_DEVICE_DEVICEGET,
487 (_SlArgSize_t)sizeof(SlDeviceSetGet_t),
488 (_SlArgSize_t)sizeof(SlDeviceSetGet_t)
489 };
490
sl_DeviceGet(const _u8 DeviceGetId,_u8 * pOption,_u16 * pConfigLen,_u8 * pValues)491 _i16 sl_DeviceGet(const _u8 DeviceGetId, _u8 *pOption,_u16 *pConfigLen, _u8 *pValues)
492 {
493 _SlDeviceMsgGet_u Msg;
494 _SlCmdExt_t CmdExt;
495
496 /* verify that this api is allowed. if not allowed then
497 ignore the API execution and return immediately with an error */
498 VERIFY_API_ALLOWED(SL_OPCODE_SILO_DEVICE);
499
500 if (*pConfigLen == 0)
501 {
502 return SL_EZEROLEN;
503 }
504
505 if( pOption )
506 {
507
508 _SlDrvResetCmdExt(&CmdExt);
509 CmdExt.RxPayloadLen = (_i16)*pConfigLen;
510 CmdExt.pRxPayload = (_u8 *)pValues;
511
512 Msg.Cmd.DeviceSetId = DeviceGetId;
513
514 Msg.Cmd.Option = (_u16)*pOption;
515
516 VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlDeviceGetCmdCtrl, &Msg, &CmdExt));
517
518 if( pOption )
519 {
520 *pOption = (_u8)Msg.Rsp.Option;
521 }
522
523 if (CmdExt.RxPayloadLen < CmdExt.ActualRxPayloadLen)
524 {
525 *pConfigLen = (_u16)CmdExt.RxPayloadLen;
526
527 return SL_ESMALLBUF;
528 }
529 else
530 {
531 *pConfigLen = (_u16)CmdExt.ActualRxPayloadLen;
532 }
533
534 return (_i16)Msg.Rsp.Status;
535 }
536 else
537 {
538 return SL_RET_CODE_INVALID_INPUT;
539 }
540 }
541 #endif
542
543 /******************************************************************************
544 sl_DeviceSet
545 ******************************************************************************/
546 typedef union
547 {
548 SlDeviceSetGet_t Cmd;
549 _BasicResponse_t Rsp;
550 }_SlDeviceMsgSet_u;
551
552
553
554 #if _SL_INCLUDE_FUNC(sl_DeviceSet)
555
556 static const _SlCmdCtrl_t _SlDeviceSetCmdCtrl =
557 {
558 SL_OPCODE_DEVICE_DEVICESET,
559 (_SlArgSize_t)sizeof(SlDeviceSetGet_t),
560 (_SlArgSize_t)sizeof(_BasicResponse_t)
561 };
562
sl_DeviceSet(const _u8 DeviceSetId,const _u8 Option,const _u16 ConfigLen,const _u8 * pValues)563 _i16 sl_DeviceSet(const _u8 DeviceSetId ,const _u8 Option,const _u16 ConfigLen,const _u8 *pValues)
564 {
565 _SlDeviceMsgSet_u Msg;
566 _SlCmdExt_t CmdExt;
567
568 /* verify that this api is allowed. if not allowed then
569 ignore the API execution and return immediately with an error */
570 VERIFY_API_ALLOWED(SL_OPCODE_SILO_DEVICE);
571
572 _SlDrvResetCmdExt(&CmdExt);
573
574 CmdExt.TxPayload1Len = (ConfigLen+3) & (~3);
575 CmdExt.pTxPayload1 = (_u8 *)pValues;
576
577 Msg.Cmd.DeviceSetId = DeviceSetId;
578 Msg.Cmd.ConfigLen = ConfigLen;
579 Msg.Cmd.Option = Option;
580
581 VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlDeviceSetCmdCtrl, &Msg, &CmdExt));
582
583 return (_i16)Msg.Rsp.status;
584 }
585 #endif
586
587
588 /******************************************************************************
589 _SlDeviceEventHandler - handles internally device async events
590 ******************************************************************************/
_SlDeviceEventHandler(void * pEventInfo)591 _SlReturnVal_t _SlDeviceEventHandler(void* pEventInfo)
592 {
593 DeviceEventInfo_t* pInfo = (DeviceEventInfo_t*)pEventInfo;
594 _SlResponseHeader_t* pHdr = (_SlResponseHeader_t *)pInfo->pAsyncMsgBuff;
595 _BasicResponse_t *pMsgArgs = (_BasicResponse_t *)_SL_RESP_ARGS_START(pHdr);
596 SlDeviceEvent_t DeviceEvent;
597
598 _SlDrvMemZero(&DeviceEvent, sizeof(DeviceEvent));
599
600 switch(pHdr->GenHeader.Opcode)
601 {
602 case SL_OPCODE_DEVICE_INITCOMPLETE:
603 _SlDeviceHandleAsync_InitComplete(pHdr);
604 break;
605 case SL_OPCODE_DEVICE_STOP_ASYNC_RESPONSE:
606 _SlDeviceHandleAsync_Stop(pHdr);
607 break;
608 case SL_OPCODE_DEVICE_RESET_REQUEST_ASYNC_EVENT:
609 {
610 SlDeviceResetRequestData_t *pResetRequestData = (SlDeviceResetRequestData_t*)pMsgArgs;
611
612 #if defined(slcb_DeviceGeneralEvtHdlr) || defined (EXT_LIB_REGISTERED_GENERAL_EVENTS)
613 if (pResetRequestData->Caller == SL_DEVICE_RESET_REQUEST_CALLER_PROVISIONING_EXTERNAL_CONFIGURATION)
614 {
615 /* call the registered events handlers (application/external lib) */
616 DeviceEvent.Id = SL_DEVICE_EVENT_RESET_REQUEST;
617 DeviceEvent.Data.ResetRequest.Status = 0;
618 DeviceEvent.Data.ResetRequest.Caller = pResetRequestData->Caller;
619 _SlDrvHandleGeneralEvents(&DeviceEvent);
620 break;
621 }
622 #endif
623
624 if (!_SlDrvIsApiInProgress() && SL_IS_PROVISIONING_IN_PROGRESS)
625 {
626 if (pResetRequestData->SessionNumber != DeviceCB.ResetRequestSessionNumber)
627 {
628 /* store the last session number */
629 DeviceCB.ResetRequestSessionNumber = pResetRequestData->SessionNumber;
630
631 /* perform the reset request */
632 _SlDeviceHandleResetRequestInternally();
633 }
634 }
635 }
636 break;
637
638 case SL_OPCODE_DEVICE_ABORT:
639 {
640 /* release global lock of cmd context */
641 if (pInfo->bInCmdContext == TRUE)
642 {
643 SL_DRV_LOCK_GLOBAL_UNLOCK(TRUE);
644 }
645
646 _SlDrvHandleFatalError(SL_DEVICE_EVENT_FATAL_DEVICE_ABORT,
647 *((_u32*)pMsgArgs - 1), /* Abort type */
648 *((_u32*)pMsgArgs)); /* Abort data */
649 }
650 break;
651
652 case SL_OPCODE_DEVICE_DEVICE_ASYNC_GENERAL_ERROR:
653 {
654 #if defined(slcb_DeviceGeneralEvtHdlr) || defined (EXT_LIB_REGISTERED_GENERAL_EVENTS)
655
656 DeviceEvent.Id = SL_DEVICE_EVENT_ERROR;
657 DeviceEvent.Data.Error.Code = pMsgArgs->status;
658 DeviceEvent.Data.Error.Source = (SlDeviceSource_e)pMsgArgs->sender;
659 _SlDrvHandleGeneralEvents(&DeviceEvent);
660 #endif
661 }
662 break;
663
664 case SL_OPCODE_DEVICE_FLOW_CTRL_ASYNC_EVENT:
665 _SlFlowContSet((void *)pHdr);
666 break;
667 default:
668 SL_ERROR_TRACE2(MSG_306, "ASSERT: _SlDeviceEventHandler : invalid opcode = 0x%x = %1", pHdr->GenHeader.Opcode, pHdr->GenHeader.Opcode);
669 }
670
671 return SL_OS_RET_CODE_OK;
672 }
673
674
_SlDeviceResetRequestInitCompletedCB(_u32 Status,SlDeviceInitInfo_t * DeviceInitInfo)675 void _SlDeviceResetRequestInitCompletedCB(_u32 Status, SlDeviceInitInfo_t *DeviceInitInfo)
676 {
677 /* Do nothing...*/
678 }
679
680
_SlDeviceHandleResetRequestInternally(void)681 void _SlDeviceHandleResetRequestInternally(void)
682 {
683 _u8 irqCountLast = RxIrqCnt;
684 #if (defined(slcb_GetTimestamp))
685 _SlTimeoutParams_t TimeoutInfo={0};
686
687 _SlDrvStartMeasureTimeout(&TimeoutInfo, 2*RESET_REQUEST_STOP_TIMEOUT);
688 #endif
689
690 /* Here we send stop command with timeout, but the API will not blocked
691 Till the stop complete event is received as we in the middle of async event handling */
692 sl_Stop(RESET_REQUEST_STOP_TIMEOUT);
693
694 /* wait till the stop complete cmd & async
695 event messages are received (2 Irqs) */
696 do
697 {
698 #if (defined(slcb_GetTimestamp))
699 if (_SlDrvIsTimeoutExpired(&TimeoutInfo))
700 {
701 break;
702 }
703 #endif
704 }
705 while((RxIrqCnt - irqCountLast) < 2);
706
707 /* start the device again */
708 sl_Start(DeviceCB.pIfHdl, DeviceCB.pDevName ,_SlDeviceResetRequestInitCompletedCB);
709
710 }
711
712
713
714 /******************************************************************************
715 sl_DeviceStat
716 ******************************************************************************/
717
sl_DeviceStatStart(const _u32 Flags)718 _i16 sl_DeviceStatStart(const _u32 Flags) // start collecting the statistics
719 {
720 SL_DRV_PROTECTION_OBJ_LOCK_FOREVER();
721 if(SL_IS_WLAN_RX_STAT_IN_PROGRESS)
722 {
723 SL_DRV_PROTECTION_OBJ_UNLOCK();
724 return SL_RET_CODE_WLAN_RX_STAT_IN_PROGRESS;
725 }
726 else
727 {
728 /* turn on flag indication for RX statistics is in progress
729 * to avoid parallel "starts" between
730 * Device statistics API and RX statistics API */
731 SL_SET_DEVICE_STAT_IN_PROGRESS;
732 SL_DRV_PROTECTION_OBJ_UNLOCK();
733 /* verify that this api is allowed. if not allowed then
734 ignore the API execution and return immediately with an error */
735 VERIFY_API_ALLOWED(SL_OPCODE_SILO_WLAN);
736 return _SlDrvBasicCmd(SL_OPCODE_WLAN_STARTRXSTATCOMMAND);
737 }
738
739 }
740
sl_DeviceStatGet(const _u16 ConfigId,_u16 length,void * buffer)741 _i16 sl_DeviceStatGet(const _u16 ConfigId,_u16 length,void* buffer)
742 {
743 _i16 RetVal = 0;
744 SL_DRV_PROTECTION_OBJ_LOCK_FOREVER();
745 /* Device statistics and Rx statistics cannot run parallel */
746 if(SL_IS_WLAN_RX_STAT_IN_PROGRESS)
747 {
748 SL_DRV_PROTECTION_OBJ_UNLOCK();
749 return SL_RET_CODE_WLAN_RX_STAT_IN_PROGRESS;
750 }
751 else
752 {
753 SL_DRV_PROTECTION_OBJ_UNLOCK();
754 if(SL_DEVICE_STAT_WLAN_RX == ConfigId )
755 {
756 /* In this case we use SL_OPCODE_WLAN_GETRXSTATCOMMAND even though we are at "Device" module -
757 * duo to the fact we want keep this API to call the exact same deprecated API which called from Wlan */
758 _SlCmdCtrl_t CmdCtrl = {SL_OPCODE_WLAN_GETRXSTATCOMMAND, 0, (_SlArgSize_t)sizeof(SlDeviceGetStat_t)};
759
760 /* verify that this api is allowed. if not allowed then
761 ignore the API execution and return immediately with an error */
762 VERIFY_API_ALLOWED(SL_OPCODE_SILO_WLAN);
763
764 _SlDrvMemZero(buffer, (_u16)sizeof(SlDeviceGetStat_t));
765 VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&CmdCtrl, buffer, NULL));
766
767 }
768 else
769 {
770 _u8 configOpt = ConfigId;
771 RetVal = sl_DeviceGet(SL_DEVICE_GENERAL,&configOpt,&length,(_u8* )buffer);
772 }
773
774 return RetVal;
775 }
776 }
777
sl_DeviceStatStop(const _u32 Flags)778 _i16 sl_DeviceStatStop(const _u32 Flags) //stop collecting the statistics
779 {
780 SL_DRV_PROTECTION_OBJ_LOCK_FOREVER();
781 if(SL_IS_WLAN_RX_STAT_IN_PROGRESS)
782 {
783 SL_DRV_PROTECTION_OBJ_UNLOCK();
784 return SL_RET_CODE_WLAN_RX_STAT_IN_PROGRESS;
785 }
786 else
787 {
788 SL_UNSET_DEVICE_STAT_IN_PROGRESS;
789 SL_DRV_PROTECTION_OBJ_UNLOCK();
790 /* verify that this api is allowed. if not allowed then
791 ignore the API execution and return immediately with an error */
792 VERIFY_API_ALLOWED(SL_OPCODE_SILO_WLAN);
793
794 return _SlDrvBasicCmd(SL_OPCODE_WLAN_STOPRXSTATCOMMAND);
795
796 }
797
798 }
799 /******************************************************************************
800 sl_DeviceUartSetMode
801 ******************************************************************************/
802 #ifdef SL_IF_TYPE_UART
803 typedef union
804 {
805 SlDeviceUartSetModeCommand_t Cmd;
806 SlDeviceUartSetModeResponse_t Rsp;
807 }_SlUartSetModeMsg_u;
808
809
810 #if _SL_INCLUDE_FUNC(sl_DeviceUartSetMode)
811
812
813 const _SlCmdCtrl_t _SlUartSetModeCmdCtrl =
814 {
815 SL_OPCODE_DEVICE_SETUARTMODECOMMAND,
816 (_SlArgSize_t)sizeof(SlDeviceUartSetModeCommand_t),
817 (_SlArgSize_t)sizeof(SlDeviceUartSetModeResponse_t)
818 };
819
sl_DeviceUartSetMode(const SlDeviceUartIfParams_t * pUartParams)820 _i16 sl_DeviceUartSetMode(const SlDeviceUartIfParams_t *pUartParams)
821 {
822 _SlUartSetModeMsg_u Msg;
823 _u32 magicCode = (_u32)0xFFFFFFFF;
824
825 Msg.Cmd.BaudRate = pUartParams->BaudRate;
826 Msg.Cmd.FlowControlEnable = pUartParams->FlowControlEnable;
827
828
829 VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlUartSetModeCmdCtrl, &Msg, NULL));
830
831 /* cmd response OK, we can continue with the handshake */
832 if (SL_RET_CODE_OK == Msg.Rsp.status)
833 {
834 sl_IfMaskIntHdlr();
835
836 /* Close the comm port */
837 sl_IfClose(g_pCB->FD);
838
839 /* Re-open the comm port */
840 sl_IfOpen((void * )pUartParams, SL_IF_UART_REOPEN_FLAGS);
841
842 sl_IfUnMaskIntHdlr();
843
844 /* send the magic code and wait for the response */
845 sl_IfWrite(g_pCB->FD, (_u8* )&magicCode, 4);
846
847 magicCode = UART_SET_MODE_MAGIC_CODE;
848 sl_IfWrite(g_pCB->FD, (_u8* )&magicCode, 4);
849
850 /* clear magic code */
851 magicCode = 0;
852
853 /* wait (blocking) till the magic code to be returned from device */
854 sl_IfRead(g_pCB->FD, (_u8* )&magicCode, 4);
855
856 /* check for the received magic code matching */
857 if (UART_SET_MODE_MAGIC_CODE != magicCode)
858 {
859 _SL_ASSERT(0);
860 }
861 }
862
863 return (_i16)Msg.Rsp.status;
864 }
865 #endif
866 #endif
867
868