1 /*
2 * txPort.c
3 *
4 * Copyright(c) 1998 - 2010 Texas Instruments. All rights reserved.
5 * All rights reserved.
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 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 * * Neither the name Texas Instruments nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34
35 /****************************************************************************
36 *
37 * MODULE: txPort.c
38 *
39 * PURPOSE: Multiplexes between the management and data queues.
40 *
41 * DESCRIPTION:
42 * ============
43 * The Tx port state machine multiplexes between the management and data queues
44 * according to the management queues requests.
45 *
46 ****************************************************************************/
47
48 #define __FILE_ID__ FILE_ID_62
49 #include "commonTypes.h"
50 #include "tidef.h"
51 #include "osApi.h"
52 #include "report.h"
53 #include "DataCtrl_Api.h"
54 #include "DrvMainModules.h"
55
56
57 typedef enum
58 {
59 MUX_MGMT_QUEUES, /* The management queues have access to the Tx path. */
60 MUX_DATA_QUEUES /* The data queues have access to the Tx path. */
61 } EQueuesMuxState;
62
63 typedef enum
64 {
65 QUEUE_ACTION_NONE,
66 QUEUE_ACTION_STOP,
67 QUEUE_ACTION_WAKE
68 } EQueueAction;
69
70 /* The txPort module object. */
71 typedef struct
72 {
73 TI_HANDLE hOs;
74 TI_HANDLE hReport;
75 TI_HANDLE hTxDataQ;
76 TI_HANDLE hTxMgmtQ;
77
78 EQueuesMuxState queuesMuxState;
79 TI_BOOL txSuspended;
80 TI_BOOL mgmtQueueEnabled;
81 TI_BOOL dataQueueEnabled;
82 } TTxPortObj;
83
84 /*
85 * The txPort local functions:
86 */
87 static void updateQueuesStates(TTxPortObj *pTxPort);
88
89 /****************************************************************************
90 * txPort_Create()
91 ****************************************************************************
92 * DESCRIPTION: Create the txPort module object
93 *
94 * INPUTS: None
95 *
96 * OUTPUT: None
97 *
98 * RETURNS: The Created object
99 ****************************************************************************/
txPort_create(TI_HANDLE hOs)100 TI_HANDLE txPort_create(TI_HANDLE hOs)
101 {
102 TTxPortObj *pTxPort;
103
104 pTxPort = os_memoryAlloc(hOs, sizeof(TTxPortObj));
105 if (pTxPort == NULL)
106 return NULL;
107
108 os_memoryZero(hOs, pTxPort, sizeof(TTxPortObj));
109
110 pTxPort->hOs = hOs;
111
112 return( (TI_HANDLE)pTxPort );
113 }
114
115
116 /****************************************************************************
117 * txPort_unLoad()
118 ****************************************************************************
119 * DESCRIPTION: Unload the txPort module object
120 *
121 * INPUTS: hTxPort - The object to free
122 *
123 * OUTPUT: None
124 *
125 * RETURNS: TI_OK
126 ****************************************************************************/
txPort_unLoad(TI_HANDLE hTxPort)127 TI_STATUS txPort_unLoad(TI_HANDLE hTxPort)
128 {
129 TTxPortObj *pTxPort = (TTxPortObj *)hTxPort;
130
131 if (pTxPort)
132 os_memoryFree(pTxPort->hOs, pTxPort, sizeof(TTxPortObj));
133
134 return TI_OK;
135 }
136
137
138 /****************************************************************************
139 * txPort_init()
140 ****************************************************************************
141 * DESCRIPTION: Configure the txPort module object
142 *
143 * INPUTS: The needed TI handles
144 *
145 * OUTPUT: None
146 *
147 * RETURNS: void
148 ****************************************************************************/
txPort_init(TStadHandlesList * pStadHandles)149 void txPort_init (TStadHandlesList *pStadHandles)
150 {
151 TTxPortObj *pTxPort = (TTxPortObj *)(pStadHandles->hTxPort);
152
153 pTxPort->hReport = pStadHandles->hReport;
154 pTxPort->hTxDataQ = pStadHandles->hTxDataQ;
155 pTxPort->hTxMgmtQ = pStadHandles->hTxMgmtQ;
156
157 pTxPort->queuesMuxState = MUX_MGMT_QUEUES;
158 pTxPort->txSuspended = TI_FALSE;
159 pTxPort->mgmtQueueEnabled = TI_TRUE;
160 pTxPort->dataQueueEnabled = TI_FALSE;
161 }
162
163
164 /****************************************************************************
165 * txPort_enableData()
166 ****************************************************************************
167 * DESCRIPTION: Called by the txMgmtQueue SM when the Tx path CAN be used by the
168 * data-queues (i.e. it's not needed for mgmt). Update the queues accordingly.
169 ****************************************************************************/
txPort_enableData(TI_HANDLE hTxPort)170 void txPort_enableData(TI_HANDLE hTxPort)
171 {
172 TTxPortObj *pTxPort = (TTxPortObj *)hTxPort;
173
174 pTxPort->queuesMuxState = MUX_DATA_QUEUES;
175 updateQueuesStates(pTxPort);
176 }
177
178
179 /****************************************************************************
180 * txPort_enableMgmt()
181 ****************************************************************************
182 * DESCRIPTION: Called by the txMgmtQueue SM when the Tx path CAN'T be used by the
183 * data-queues (i.e. it's needed for mgmt). Update the queues accordingly.
184 ****************************************************************************/
txPort_enableMgmt(TI_HANDLE hTxPort)185 void txPort_enableMgmt(TI_HANDLE hTxPort)
186 {
187 TTxPortObj *pTxPort = (TTxPortObj *)hTxPort;
188
189 pTxPort->queuesMuxState = MUX_MGMT_QUEUES;
190 updateQueuesStates(pTxPort);
191 }
192
193
194 /****************************************************************************
195 * txPort_suspendTx()
196 ****************************************************************************
197 * DESCRIPTION: Used by STAD applications (e.g. recovery) to temporarily suspend the Tx path.
198 ****************************************************************************/
txPort_suspendTx(TI_HANDLE hTxPort)199 void txPort_suspendTx(TI_HANDLE hTxPort)
200 {
201 TTxPortObj *pTxPort = (TTxPortObj *)hTxPort;
202
203 pTxPort->txSuspended = TI_TRUE;
204 updateQueuesStates(pTxPort);
205 }
206
207
208 /****************************************************************************
209 * txPort_resumeTx()
210 ****************************************************************************
211 * DESCRIPTION: Used by STAD applications (e.g. recovery) to resume Tx path after suspended.
212 ****************************************************************************/
txPort_resumeTx(TI_HANDLE hTxPort)213 void txPort_resumeTx(TI_HANDLE hTxPort)
214 {
215 TTxPortObj *pTxPort = (TTxPortObj *)hTxPort;
216
217 pTxPort->txSuspended = TI_FALSE;
218 updateQueuesStates(pTxPort);
219 }
220
221
222 /****************************************************************************
223 * updateQueuesStates()
224 ****************************************************************************
225 * DESCRIPTION: Switch the Data-Queue and Mgmt-Queue Tx on/off (stop/wake)
226 * according to the current port conditions.
227 ****************************************************************************/
updateQueuesStates(TTxPortObj * pTxPort)228 static void updateQueuesStates (TTxPortObj *pTxPort)
229 {
230 EQueueAction mgmtQueueAction = QUEUE_ACTION_NONE;
231 EQueueAction dataQueueAction = QUEUE_ACTION_NONE;
232
233 /*
234 * If the Tx path is not suspended:
235 */
236 if (!pTxPort->txSuspended)
237 {
238 /* If mgmt-queues should be enabled, set required actions (awake mgmt and stop data if needed). */
239 if (pTxPort->queuesMuxState == MUX_MGMT_QUEUES)
240 {
241 if ( !pTxPort->mgmtQueueEnabled )
242 mgmtQueueAction = QUEUE_ACTION_WAKE;
243 if ( pTxPort->dataQueueEnabled )
244 dataQueueAction = QUEUE_ACTION_STOP;
245 }
246
247 /* If data-queues should be enabled, set required actions (stop mgmt and awake data if needed). */
248 else
249 {
250 if ( pTxPort->mgmtQueueEnabled )
251 mgmtQueueAction = QUEUE_ACTION_STOP;
252 if ( !pTxPort->dataQueueEnabled )
253 dataQueueAction = QUEUE_ACTION_WAKE;
254 }
255 }
256
257 /*
258 * If the Tx path is not available (Xfer is busy or suspension is requested),
259 * set required actions (stop mgmt and data if needed).
260 */
261 else
262 {
263 if ( pTxPort->mgmtQueueEnabled )
264 mgmtQueueAction = QUEUE_ACTION_STOP;
265 if ( pTxPort->dataQueueEnabled )
266 dataQueueAction = QUEUE_ACTION_STOP;
267 }
268
269
270 #ifdef TI_DBG
271 TRACE1(pTxPort->hReport, REPORT_SEVERITY_INFORMATION, ": queuesMuxState = , TxSuspend = %d\n", pTxPort->txSuspended);
272
273 TRACE2(pTxPort->hReport, REPORT_SEVERITY_INFORMATION, ": PrevMgmtEnabled = %d, PrevDataEnabled = %d, MgmtAction = , DataAction = \n", pTxPort->mgmtQueueEnabled, pTxPort->dataQueueEnabled);
274 #endif /* TI_DBG */
275
276 /*
277 * Execute the required actions.
278 * Note: This is done at the end of this function because it may start a sequence that will call it again!!
279 * Always do WAKE action after STOP action, since WAKE may lead to more activities!!
280 */
281 if (mgmtQueueAction == QUEUE_ACTION_STOP)
282 {
283 pTxPort->mgmtQueueEnabled = TI_FALSE;
284 txMgmtQ_StopAll (pTxPort->hTxMgmtQ);
285 }
286 if (dataQueueAction == QUEUE_ACTION_STOP)
287 {
288 pTxPort->dataQueueEnabled = TI_FALSE;
289 txDataQ_StopAll (pTxPort->hTxDataQ);
290 }
291 if (mgmtQueueAction == QUEUE_ACTION_WAKE)
292 {
293 pTxPort->mgmtQueueEnabled = TI_TRUE;
294 txMgmtQ_WakeAll (pTxPort->hTxMgmtQ);
295 }
296 if (dataQueueAction == QUEUE_ACTION_WAKE)
297 {
298 pTxPort->dataQueueEnabled = TI_TRUE;
299 txDataQ_WakeAll (pTxPort->hTxDataQ);
300 }
301 }
302
303