Home | History | Annotate | Download | only in Data_link
      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  ****************************************************************************/
    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  ****************************************************************************/
    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  ****************************************************************************/
    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  ****************************************************************************/
    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  ****************************************************************************/
    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  ****************************************************************************/
    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  ****************************************************************************/
    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  ****************************************************************************/
    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  ****************************************************************************/
    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 
    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