1 /*
2  * spawn.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 /*****************************************************************************/
40 /* Include files                                                             */
41 /*****************************************************************************/
42 #include <ti/drivers/net/wifi/simplelink.h>
43 #include <ti/drivers/net/wifi/source/protocol.h>
44 #include <ti/drivers/net/wifi/source/driver.h>
45 
46 #if (defined (SL_PLATFORM_MULTI_THREADED)) && (!defined (SL_PLATFORM_EXTERNAL_SPAWN))
47 
48 
49 typedef struct
50 {
51     _SlSyncObj_t                SyncObj;
52     _u8                         IrqWriteCnt;
53     _u8                         IrqReadCnt;
54     void*                       pIrqFuncValue;
55 
56 #ifdef SL_PLATFORM_MULTI_THREADED
57     _u32 						ThreadId;
58 #endif
59 }_SlInternalSpawnCB_t;
60 
61 _SlInternalSpawnCB_t g_SlInternalSpawnCB;
62 
_SlInternalIsItSpawnThread(_u32 ThreadId)63 _u8 _SlInternalIsItSpawnThread(_u32 ThreadId)
64 {
65 	return (ThreadId == g_SlInternalSpawnCB.ThreadId);
66 }
67 
_SlInternalSpawnWaitForEvent(void)68 void _SlInternalSpawnWaitForEvent(void)
69 {
70 
71 	sl_SyncObjWait(&g_SlInternalSpawnCB.SyncObj, SL_OS_WAIT_FOREVER);
72 
73 	/*
74 	* call the processQ function will handle the pending async
75 	* events already read from NWP, and only wait for handling
76 	* the events that have been read only during command execution. */
77 	_SlSpawnMsgListProcess();
78 
79 	/* handle IRQ requests */
80 	while (g_SlInternalSpawnCB.IrqWriteCnt != g_SlInternalSpawnCB.IrqReadCnt)
81 	{
82 		/* handle the ones that came from ISR context*/
83 		_SlDrvMsgReadSpawnCtx(g_SlInternalSpawnCB.pIrqFuncValue);
84 		g_SlInternalSpawnCB.IrqReadCnt++;
85 	}
86 
87 }
88 
_SlInternalSpawnTaskEntry()89 void* _SlInternalSpawnTaskEntry()
90 {
91 
92     /* create and clear the sync object */
93     sl_SyncObjCreate(&g_SlInternalSpawnCB.SyncObj,"SlSpawnSync");
94     sl_SyncObjWait(&g_SlInternalSpawnCB.SyncObj,SL_OS_NO_WAIT);
95 
96     g_SlInternalSpawnCB.ThreadId = 0xFFFFFFFF;
97 
98 #ifdef SL_PLATFORM_MULTI_THREADED
99 	g_SlInternalSpawnCB.ThreadId = (_i32)sl_GetThreadID();
100 #endif
101 
102     g_SlInternalSpawnCB.IrqWriteCnt = 0;
103     g_SlInternalSpawnCB.IrqReadCnt = 0;
104     g_SlInternalSpawnCB.pIrqFuncValue = NULL;
105 
106     /* here we ready to execute entries */
107     while (TRUE)
108     {
109 	    /* wait for event */
110 	    _SlInternalSpawnWaitForEvent();
111     }
112 }
113 
_SlInternalSpawn(_SlSpawnEntryFunc_t pEntry,void * pValue,_u32 flags)114 _i16 _SlInternalSpawn(_SlSpawnEntryFunc_t pEntry , void* pValue , _u32 flags)
115 {
116     _i16 Res = 0;
117 
118     /*  Increment the counter that specifies that async event has received
119         from interrupt context and should be handled by the internal spawn task */
120     if ((flags & SL_SPAWN_FLAG_FROM_SL_IRQ_HANDLER) || (flags & SL_SPAWN_FLAG_FROM_CMD_CTX))
121     {
122         g_SlInternalSpawnCB.IrqWriteCnt++;
123         g_SlInternalSpawnCB.pIrqFuncValue = pValue;
124         SL_DRV_SYNC_OBJ_SIGNAL_FROM_IRQ(&g_SlInternalSpawnCB.SyncObj);
125         return Res;
126     }
127     else if (flags & SL_SPAWN_FLAG_FROM_CMD_PROCESS)
128     {
129         SL_DRV_SYNC_OBJ_SIGNAL(&g_SlInternalSpawnCB.SyncObj);
130     }
131 
132     return Res;
133 }
134 
135 #endif
136