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