• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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