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