• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * txPort.c
3  *
4  * Copyright(c) 1998 - 2009 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 #ifdef TI_DBG
89 static char *txPortMuxStateNameStr(EQueuesMuxState queuesMuxState);
90 static char *txPortActionNameStr(EQueueAction queueAction);
91 #endif
92 
93 
94 
95 /****************************************************************************
96  *                      txPort_Create()
97  ****************************************************************************
98  * DESCRIPTION:	Create the txPort module object
99  *
100  * INPUTS:	None
101  *
102  * OUTPUT:	None
103  *
104  * RETURNS:	The Created object
105  ****************************************************************************/
txPort_create(TI_HANDLE hOs)106 TI_HANDLE txPort_create(TI_HANDLE hOs)
107 {
108 	TTxPortObj *pTxPort;
109 
110 	pTxPort = os_memoryAlloc(hOs, sizeof(TTxPortObj));
111 	if (pTxPort == NULL)
112 		return NULL;
113 
114 	os_memoryZero(hOs, pTxPort, sizeof(TTxPortObj));
115 
116 	pTxPort->hOs = hOs;
117 
118 	return( (TI_HANDLE)pTxPort );
119 }
120 
121 
122 /****************************************************************************
123  *                      txPort_unLoad()
124  ****************************************************************************
125  * DESCRIPTION:	Unload the txPort module object
126  *
127  * INPUTS:	hTxPort - The object to free
128  *
129  * OUTPUT:	None
130  *
131  * RETURNS:	TI_OK
132  ****************************************************************************/
txPort_unLoad(TI_HANDLE hTxPort)133 TI_STATUS txPort_unLoad(TI_HANDLE hTxPort)
134 {
135 	TTxPortObj *pTxPort = (TTxPortObj *)hTxPort;
136 
137 	if (pTxPort)
138 		os_memoryFree(pTxPort->hOs, pTxPort, sizeof(TTxPortObj));
139 
140 	return TI_OK;
141 }
142 
143 
144 /****************************************************************************
145  *                      txPort_init()
146  ****************************************************************************
147  * DESCRIPTION:	Configure the txPort module object
148  *
149  * INPUTS:	The needed TI handles
150  *
151  * OUTPUT:	None
152  *
153  * RETURNS:	void
154  ****************************************************************************/
txPort_init(TStadHandlesList * pStadHandles)155 void txPort_init (TStadHandlesList *pStadHandles)
156 {
157 	TTxPortObj *pTxPort = (TTxPortObj *)(pStadHandles->hTxPort);
158 
159 	pTxPort->hReport  = pStadHandles->hReport;
160 	pTxPort->hTxDataQ = pStadHandles->hTxDataQ;
161 	pTxPort->hTxMgmtQ = pStadHandles->hTxMgmtQ;
162 
163 	pTxPort->queuesMuxState	  = MUX_MGMT_QUEUES;
164 	pTxPort->txSuspended	  = TI_FALSE;
165 	pTxPort->mgmtQueueEnabled = TI_TRUE;
166 	pTxPort->dataQueueEnabled = TI_FALSE;
167 }
168 
169 
170 /****************************************************************************
171  *                      txPort_enableData()
172  ****************************************************************************
173  * DESCRIPTION:	Called by the txMgmtQueue SM when the Tx path CAN be used by the
174  *				  data-queues (i.e. it's not needed for mgmt). Update the queues accordingly.
175  ****************************************************************************/
txPort_enableData(TI_HANDLE hTxPort)176 void txPort_enableData(TI_HANDLE hTxPort)
177 {
178 	TTxPortObj *pTxPort = (TTxPortObj *)hTxPort;
179 
180 	pTxPort->queuesMuxState = MUX_DATA_QUEUES;
181 	updateQueuesStates(pTxPort);
182 }
183 
184 
185 /****************************************************************************
186  *                      txPort_enableMgmt()
187  ****************************************************************************
188  * DESCRIPTION:	Called by the txMgmtQueue SM when the Tx path CAN'T be used by the
189  *				  data-queues (i.e. it's needed for mgmt). Update the queues accordingly.
190  ****************************************************************************/
txPort_enableMgmt(TI_HANDLE hTxPort)191 void txPort_enableMgmt(TI_HANDLE hTxPort)
192 {
193 	TTxPortObj *pTxPort = (TTxPortObj *)hTxPort;
194 
195 	pTxPort->queuesMuxState = MUX_MGMT_QUEUES;
196 	updateQueuesStates(pTxPort);
197 }
198 
199 
200 /****************************************************************************
201  *                      txPort_suspendTx()
202  ****************************************************************************
203  * DESCRIPTION:	Used by STAD applications (e.g. recovery) to temporarily suspend the Tx path.
204  ****************************************************************************/
txPort_suspendTx(TI_HANDLE hTxPort)205 void txPort_suspendTx(TI_HANDLE hTxPort)
206 {
207 	TTxPortObj *pTxPort = (TTxPortObj *)hTxPort;
208 
209 	pTxPort->txSuspended = TI_TRUE;
210 	updateQueuesStates(pTxPort);
211 }
212 
213 
214 /****************************************************************************
215  *                      txPort_resumeTx()
216  ****************************************************************************
217  * DESCRIPTION:	Used by STAD applications (e.g. recovery) to resume Tx path after suspended.
218  ****************************************************************************/
txPort_resumeTx(TI_HANDLE hTxPort)219 void txPort_resumeTx(TI_HANDLE hTxPort)
220 {
221 	TTxPortObj *pTxPort = (TTxPortObj *)hTxPort;
222 
223 	pTxPort->txSuspended = TI_FALSE;
224 	updateQueuesStates(pTxPort);
225 }
226 
227 
228 /****************************************************************************
229  *                      updateQueuesStates()
230  ****************************************************************************
231  * DESCRIPTION:	 Switch the Data-Queue and Mgmt-Queue Tx on/off (stop/wake)
232  *				   according to the current port conditions.
233  ****************************************************************************/
updateQueuesStates(TTxPortObj * pTxPort)234 static void updateQueuesStates (TTxPortObj *pTxPort)
235 {
236 	EQueueAction mgmtQueueAction = QUEUE_ACTION_NONE;
237 	EQueueAction dataQueueAction = QUEUE_ACTION_NONE;
238 #ifdef TI_DBG
239 	char *pMuxStateNameStr;
240 	char *pPortActionNameStr;
241 #endif
242 
243 	/*
244 	 * If the Tx path is not suspended:
245 	 */
246 	if (!pTxPort->txSuspended)
247 	{
248 		/* If mgmt-queues should be enabled, set required actions (awake mgmt and stop data if needed). */
249 		if (pTxPort->queuesMuxState == MUX_MGMT_QUEUES)
250 		{
251 			if ( !pTxPort->mgmtQueueEnabled )
252 				mgmtQueueAction = QUEUE_ACTION_WAKE;
253 			if ( pTxPort->dataQueueEnabled )
254 				dataQueueAction = QUEUE_ACTION_STOP;
255 		}
256 
257 		/* If data-queues should be enabled, set required actions (stop mgmt and awake data if needed). */
258 		else
259 		{
260 			if ( pTxPort->mgmtQueueEnabled )
261 				mgmtQueueAction = QUEUE_ACTION_STOP;
262 			if ( !pTxPort->dataQueueEnabled )
263 				dataQueueAction = QUEUE_ACTION_WAKE;
264 		}
265 	}
266 
267 	/*
268 	 * If the Tx path is not available (Xfer is busy or suspension is requested),
269 	 *   set required actions (stop mgmt and data if needed).
270 	 */
271 	else
272 	{
273 		if ( pTxPort->mgmtQueueEnabled )
274 			mgmtQueueAction = QUEUE_ACTION_STOP;
275 		if ( pTxPort->dataQueueEnabled )
276 			dataQueueAction = QUEUE_ACTION_STOP;
277 	}
278 
279 
280 #ifdef TI_DBG
281 	pMuxStateNameStr = txPortMuxStateNameStr(pTxPort->queuesMuxState);
282 	TRACE1(pTxPort->hReport, REPORT_SEVERITY_INFORMATION, ":  queuesMuxState = , TxSuspend = %d\n", pTxPort->txSuspended);
283 
284 	pPortActionNameStr = txPortActionNameStr (mgmtQueueAction);
285 	TRACE2(pTxPort->hReport, REPORT_SEVERITY_INFORMATION, ":  PrevMgmtEnabled = %d,  PrevDataEnabled = %d, MgmtAction = , DataAction = \n", pTxPort->mgmtQueueEnabled, pTxPort->dataQueueEnabled);
286 #endif /* TI_DBG */
287 
288 	/*
289 	 * Execute the required actions.
290 	 * Note: This is done at the end of this function because it may start a sequence that will call it again!!
291 	 *       Always do WAKE action after STOP action, since WAKE may lead to more activities!!
292 	 */
293 	if (mgmtQueueAction == QUEUE_ACTION_STOP)
294 	{
295 		pTxPort->mgmtQueueEnabled = TI_FALSE;
296 		txMgmtQ_StopAll (pTxPort->hTxMgmtQ);
297 	}
298 	if (dataQueueAction == QUEUE_ACTION_STOP)
299 	{
300 		pTxPort->dataQueueEnabled = TI_FALSE;
301 		txDataQ_StopAll (pTxPort->hTxDataQ);
302 	}
303 	if (mgmtQueueAction == QUEUE_ACTION_WAKE)
304 	{
305 		pTxPort->mgmtQueueEnabled = TI_TRUE;
306 		txMgmtQ_WakeAll (pTxPort->hTxMgmtQ);
307 	}
308 	if (dataQueueAction == QUEUE_ACTION_WAKE)
309 	{
310 		pTxPort->dataQueueEnabled = TI_TRUE;
311 		txDataQ_WakeAll (pTxPort->hTxDataQ);
312 	}
313 }
314 
315 
316 
317 #ifdef TI_DBG
318 
319 /****************************************************************************
320  *	Debug functions:	txPortMuxStateNameStr()
321  *                      txPortActionNameStr()
322  ****************************************************************************/
txPortMuxStateNameStr(EQueuesMuxState queuesMuxState)323 static char *txPortMuxStateNameStr(EQueuesMuxState queuesMuxState)
324 {
325 	switch (queuesMuxState)
326 	{
327 		case MUX_MGMT_QUEUES:	return "MUX_MGMT_QUEUES";
328 		case MUX_DATA_QUEUES:	return "MUX_DATA_QUEUES";
329 		default:				return "UNKNOWN STATE";
330 	}
331 }
332 
txPortActionNameStr(EQueueAction queueAction)333 static char *txPortActionNameStr(EQueueAction queueAction)
334 {
335 	switch (queueAction)
336 	{
337 		case QUEUE_ACTION_NONE:	return "QUEUE_ACTION_NONE";
338 		case QUEUE_ACTION_STOP:	return "QUEUE_ACTION_STOP";
339 		case QUEUE_ACTION_WAKE:	return "QUEUE_ACTION_WAKE";
340 		default:				return "UNKNOWN ACTION";
341 	}
342 }
343 
344 #endif /* TI_DBG */
345 
346 
347