1296177Sjhibbits/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. 2296177Sjhibbits * All rights reserved. 3296177Sjhibbits * 4296177Sjhibbits * Redistribution and use in source and binary forms, with or without 5296177Sjhibbits * modification, are permitted provided that the following conditions are met: 6296177Sjhibbits * * Redistributions of source code must retain the above copyright 7296177Sjhibbits * notice, this list of conditions and the following disclaimer. 8296177Sjhibbits * * Redistributions in binary form must reproduce the above copyright 9296177Sjhibbits * notice, this list of conditions and the following disclaimer in the 10296177Sjhibbits * documentation and/or other materials provided with the distribution. 11296177Sjhibbits * * Neither the name of Freescale Semiconductor nor the 12296177Sjhibbits * names of its contributors may be used to endorse or promote products 13296177Sjhibbits * derived from this software without specific prior written permission. 14296177Sjhibbits * 15296177Sjhibbits * 16296177Sjhibbits * ALTERNATIVELY, this software may be distributed under the terms of the 17296177Sjhibbits * GNU General Public License ("GPL") as published by the Free Software 18296177Sjhibbits * Foundation, either version 2 of that License or (at your option) any 19296177Sjhibbits * later version. 20296177Sjhibbits * 21296177Sjhibbits * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY 22296177Sjhibbits * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 23296177Sjhibbits * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24296177Sjhibbits * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY 25296177Sjhibbits * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26296177Sjhibbits * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27296177Sjhibbits * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 28296177Sjhibbits * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29296177Sjhibbits * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30296177Sjhibbits * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31296177Sjhibbits */ 32296177Sjhibbits 33296177Sjhibbits/****************************************************************************** 34296177Sjhibbits @File fm_port_im.c 35296177Sjhibbits 36296177Sjhibbits @Description FM Port Independent-Mode ... 37296177Sjhibbits*//***************************************************************************/ 38296177Sjhibbits#include "std_ext.h" 39296177Sjhibbits#include "string_ext.h" 40296177Sjhibbits#include "error_ext.h" 41296177Sjhibbits#include "fm_muram_ext.h" 42296177Sjhibbits 43296177Sjhibbits#include "fm_port.h" 44296177Sjhibbits 45296177Sjhibbits 46296177Sjhibbits#define TX_CONF_STATUS_UNSENT 0x1 47296177Sjhibbits 48296177Sjhibbits#ifdef CORE_8BIT_ACCESS_ERRATA 49296177Sjhibbits#undef WRITE_UINT16 50296177Sjhibbits#undef GET_UINT16 51296177Sjhibbits 52296177Sjhibbits#define WRITE_UINT16(addr, val) \ 53296177Sjhibbits do{ \ 54296177Sjhibbits if((int)&(addr) % 4) \ 55296177Sjhibbits WRITE_UINT32(*(uint32_t*)(uint32_t)((uint32_t)&addr & ~0x3L), \ 56296177Sjhibbits ((GET_UINT32(*(uint32_t*)(uint32_t)((uint32_t)&addr & ~0x3L)) & 0xffff0000) | (uint32_t)val)); \ 57296177Sjhibbits else \ 58296177Sjhibbits WRITE_UINT32(*(uint32_t*)&addr, \ 59296177Sjhibbits ((GET_UINT32(*(uint32_t*)&addr) & 0x0000ffff) | (uint32_t)val<<16)); \ 60296177Sjhibbits }while(0); 61296177Sjhibbits 62296177Sjhibbits#define GET_UINT16(addr) (((uint32_t)&addr%4) ? \ 63296177Sjhibbits ((uint16_t)GET_UINT32(*(uint32_t*)(uint32_t)((uint32_t)&addr & ~0x3L))): \ 64296177Sjhibbits ((uint16_t)(GET_UINT32(*(uint32_t*)(uint32_t)&addr) >> 16))) 65296177Sjhibbits#endif /* CORE_8BIT_ACCESS_ERRATA */ 66296177Sjhibbits 67296177Sjhibbits 68296177Sjhibbitstypedef enum e_TxConfType 69296177Sjhibbits{ 70296177Sjhibbits e_TX_CONF_TYPE_CHECK = 0 /**< check if all the buffers were touched by the muxator, no confirmation callback */ 71296177Sjhibbits ,e_TX_CONF_TYPE_CALLBACK = 1 /**< confirm to user all the available sent buffers */ 72296177Sjhibbits ,e_TX_CONF_TYPE_FLUSH = 3 /**< confirm all buffers plus the unsent one with an appropriate status */ 73296177Sjhibbits} e_TxConfType; 74296177Sjhibbits 75296177Sjhibbits 76296177Sjhibbitsstatic void ImException(t_Handle h_FmPort, uint32_t event) 77296177Sjhibbits{ 78296177Sjhibbits t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 79296177Sjhibbits 80296177Sjhibbits ASSERT_COND(((event & IM_EV_RX) && FmIsMaster(p_FmPort->h_Fm)) || 81296177Sjhibbits !FmIsMaster(p_FmPort->h_Fm)); 82296177Sjhibbits 83296177Sjhibbits if (event & IM_EV_RX) 84296177Sjhibbits FmPortImRx(p_FmPort); 85296177Sjhibbits if ((event & IM_EV_BSY) && p_FmPort->f_Exception) 86296177Sjhibbits p_FmPort->f_Exception(p_FmPort->h_App, e_FM_PORT_EXCEPTION_IM_BUSY); 87296177Sjhibbits} 88296177Sjhibbits 89296177Sjhibbits 90296177Sjhibbitsstatic t_Error TxConf(t_FmPort *p_FmPort, e_TxConfType confType) 91296177Sjhibbits{ 92296177Sjhibbits t_Error retVal = E_BUSY; 93296177Sjhibbits uint32_t bdStatus; 94296177Sjhibbits uint16_t savedStartBdId, confBdId; 95296177Sjhibbits 96296177Sjhibbits ASSERT_COND(p_FmPort); 97296177Sjhibbits 98296177Sjhibbits /* 99296177Sjhibbits if (confType==e_TX_CONF_TYPE_CHECK) 100296177Sjhibbits return (WfqEntryIsQueueEmpty(p_FmPort->im.h_WfqEntry) ? E_OK : E_BUSY); 101296177Sjhibbits */ 102296177Sjhibbits 103296177Sjhibbits confBdId = savedStartBdId = p_FmPort->im.currBdId; 104296177Sjhibbits bdStatus = BD_STATUS_AND_LENGTH(BD_GET(confBdId)); 105296177Sjhibbits 106296177Sjhibbits /* If R bit is set, we don't enter, or we break. 107296177Sjhibbits we run till we get to R, or complete the loop */ 108296177Sjhibbits while ((!(bdStatus & BD_R_E) || (confType == e_TX_CONF_TYPE_FLUSH)) && (retVal != E_OK)) 109296177Sjhibbits { 110296177Sjhibbits if (confType & e_TX_CONF_TYPE_CALLBACK) /* if it is confirmation with user callbacks */ 111296177Sjhibbits BD_STATUS_AND_LENGTH_SET(BD_GET(confBdId), 0); 112296177Sjhibbits 113296177Sjhibbits /* case 1: R bit is 0 and Length is set -> confirm! */ 114296177Sjhibbits if ((confType & e_TX_CONF_TYPE_CALLBACK) && (bdStatus & BD_LENGTH_MASK)) 115296177Sjhibbits { 116296177Sjhibbits if (p_FmPort->im.f_TxConf) 117296177Sjhibbits { 118296177Sjhibbits if ((confType == e_TX_CONF_TYPE_FLUSH) && (bdStatus & BD_R_E)) 119296177Sjhibbits p_FmPort->im.f_TxConf(p_FmPort->h_App, 120296177Sjhibbits BdBufferGet(XX_PhysToVirt, BD_GET(confBdId)), 121296177Sjhibbits TX_CONF_STATUS_UNSENT, 122296177Sjhibbits p_FmPort->im.p_BdShadow[confBdId]); 123296177Sjhibbits else 124296177Sjhibbits p_FmPort->im.f_TxConf(p_FmPort->h_App, 125296177Sjhibbits BdBufferGet(XX_PhysToVirt, BD_GET(confBdId)), 126296177Sjhibbits 0, 127296177Sjhibbits p_FmPort->im.p_BdShadow[confBdId]); 128296177Sjhibbits } 129296177Sjhibbits } 130296177Sjhibbits /* case 2: R bit is 0 and Length is 0 -> not used yet, nop! */ 131296177Sjhibbits 132296177Sjhibbits confBdId = GetNextBdId(p_FmPort, confBdId); 133296177Sjhibbits if (confBdId == savedStartBdId) 134296177Sjhibbits retVal = E_OK; 135296177Sjhibbits bdStatus = BD_STATUS_AND_LENGTH(BD_GET(confBdId)); 136296177Sjhibbits } 137296177Sjhibbits 138296177Sjhibbits return retVal; 139296177Sjhibbits} 140296177Sjhibbits 141296177Sjhibbitst_Error FmPortImEnable(t_FmPort *p_FmPort) 142296177Sjhibbits{ 143296177Sjhibbits uint32_t tmpReg = GET_UINT32(p_FmPort->im.p_FmPortImPram->mode); 144296177Sjhibbits WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, (uint32_t)(tmpReg & ~IM_MODE_GRC_STP)); 145296177Sjhibbits return E_OK; 146296177Sjhibbits} 147296177Sjhibbits 148296177Sjhibbitst_Error FmPortImDisable(t_FmPort *p_FmPort) 149296177Sjhibbits{ 150296177Sjhibbits uint32_t tmpReg = GET_UINT32(p_FmPort->im.p_FmPortImPram->mode); 151296177Sjhibbits WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, (uint32_t)(tmpReg | IM_MODE_GRC_STP)); 152296177Sjhibbits return E_OK; 153296177Sjhibbits} 154296177Sjhibbits 155296177Sjhibbitst_Error FmPortImRx(t_FmPort *p_FmPort) 156296177Sjhibbits{ 157296177Sjhibbits t_Handle h_CurrUserPriv, h_NewUserPriv; 158296177Sjhibbits uint32_t bdStatus; 159296177Sjhibbits volatile uint8_t buffPos; 160296177Sjhibbits uint16_t length; 161296177Sjhibbits uint16_t errors/*, reportErrors*/; 162296177Sjhibbits uint8_t *p_CurData, *p_Data; 163296177Sjhibbits uint32_t flags; 164296177Sjhibbits 165296177Sjhibbits ASSERT_COND(p_FmPort); 166296177Sjhibbits 167296177Sjhibbits flags = XX_LockIntrSpinlock(p_FmPort->h_Spinlock); 168296177Sjhibbits if (p_FmPort->lock) 169296177Sjhibbits { 170296177Sjhibbits XX_UnlockIntrSpinlock(p_FmPort->h_Spinlock, flags); 171296177Sjhibbits return E_OK; 172296177Sjhibbits } 173296177Sjhibbits p_FmPort->lock = TRUE; 174296177Sjhibbits XX_UnlockIntrSpinlock(p_FmPort->h_Spinlock, flags); 175296177Sjhibbits 176296177Sjhibbits bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId)); 177296177Sjhibbits 178296177Sjhibbits while (!(bdStatus & BD_R_E)) /* while there is data in the Rx BD */ 179296177Sjhibbits { 180296177Sjhibbits if ((p_Data = p_FmPort->im.rxPool.f_GetBuf(p_FmPort->im.rxPool.h_BufferPool, &h_NewUserPriv)) == NULL) 181296177Sjhibbits { 182296177Sjhibbits p_FmPort->lock = FALSE; 183296177Sjhibbits RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Data buffer")); 184296177Sjhibbits } 185296177Sjhibbits 186296177Sjhibbits if (p_FmPort->im.firstBdOfFrameId == IM_ILEGAL_BD_ID) 187296177Sjhibbits p_FmPort->im.firstBdOfFrameId = p_FmPort->im.currBdId; 188296177Sjhibbits 189296177Sjhibbits errors = 0; 190296177Sjhibbits p_CurData = BdBufferGet(p_FmPort->im.rxPool.f_PhysToVirt, BD_GET(p_FmPort->im.currBdId)); 191296177Sjhibbits h_CurrUserPriv = p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId]; 192296177Sjhibbits length = (uint16_t)((bdStatus & BD_L) ? 193296177Sjhibbits ((bdStatus & BD_LENGTH_MASK) - p_FmPort->im.rxFrameAccumLength): 194296177Sjhibbits (bdStatus & BD_LENGTH_MASK)); 195296177Sjhibbits p_FmPort->im.rxFrameAccumLength += length; 196296177Sjhibbits 197296177Sjhibbits /* determine whether buffer is first, last, first and last (single */ 198296177Sjhibbits /* buffer frame) or middle (not first and not last) */ 199296177Sjhibbits buffPos = (uint8_t)((p_FmPort->im.currBdId == p_FmPort->im.firstBdOfFrameId) ? 200296177Sjhibbits ((bdStatus & BD_L) ? SINGLE_BUF : FIRST_BUF) : 201296177Sjhibbits ((bdStatus & BD_L) ? LAST_BUF : MIDDLE_BUF)); 202296177Sjhibbits 203296177Sjhibbits if (bdStatus & BD_L) 204296177Sjhibbits { 205296177Sjhibbits p_FmPort->im.rxFrameAccumLength = 0; 206296177Sjhibbits p_FmPort->im.firstBdOfFrameId = IM_ILEGAL_BD_ID; 207296177Sjhibbits } 208296177Sjhibbits 209296177Sjhibbits BdBufferSet(p_FmPort->im.rxPool.f_VirtToPhys, BD_GET(p_FmPort->im.currBdId), p_Data); 210296177Sjhibbits 211296177Sjhibbits BD_STATUS_AND_LENGTH_SET(BD_GET(p_FmPort->im.currBdId), BD_R_E); 212296177Sjhibbits 213296177Sjhibbits errors = (uint16_t)((bdStatus & BD_RX_ERRORS) >> 16); 214296177Sjhibbits p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId] = h_NewUserPriv; 215296177Sjhibbits 216296177Sjhibbits p_FmPort->im.currBdId = GetNextBdId(p_FmPort, p_FmPort->im.currBdId); 217296177Sjhibbits WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.offsetOut, (uint16_t)(p_FmPort->im.currBdId<<4)); 218296177Sjhibbits /* Pass the buffer if one of the conditions is true: 219296177Sjhibbits - There are no errors 220296177Sjhibbits - This is a part of a larger frame ( the application has already received some buffers ) 221296177Sjhibbits - There is an error, but it was defined to be passed anyway. */ 222296177Sjhibbits if ((buffPos != SINGLE_BUF) || !errors || (errors & (uint16_t)(BD_ERROR_PASS_FRAME>>16))) 223296177Sjhibbits { 224296177Sjhibbits if (p_FmPort->im.f_RxStore(p_FmPort->h_App, 225296177Sjhibbits p_CurData, 226296177Sjhibbits length, 227296177Sjhibbits errors, 228296177Sjhibbits buffPos, 229296177Sjhibbits h_CurrUserPriv) == e_RX_STORE_RESPONSE_PAUSE) 230296177Sjhibbits break; 231296177Sjhibbits } 232296177Sjhibbits else if (p_FmPort->im.rxPool.f_PutBuf(p_FmPort->im.rxPool.h_BufferPool, 233296177Sjhibbits p_CurData, 234296177Sjhibbits h_CurrUserPriv)) 235296177Sjhibbits { 236296177Sjhibbits p_FmPort->lock = FALSE; 237296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Failed freeing data buffer")); 238296177Sjhibbits } 239296177Sjhibbits 240296177Sjhibbits bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId)); 241296177Sjhibbits } 242296177Sjhibbits p_FmPort->lock = FALSE; 243296177Sjhibbits return E_OK; 244296177Sjhibbits} 245296177Sjhibbits 246296177Sjhibbitsvoid FmPortConfigIM (t_FmPort *p_FmPort, t_FmPortParams *p_FmPortParams) 247296177Sjhibbits{ 248296177Sjhibbits ASSERT_COND(p_FmPort); 249296177Sjhibbits 250296177Sjhibbits SANITY_CHECK_RETURN(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 251296177Sjhibbits 252296177Sjhibbits p_FmPort->im.h_FmMuram = p_FmPortParams->specificParams.imRxTxParams.h_FmMuram; 253296177Sjhibbits p_FmPort->p_FmPortDriverParam->liodnOffset = p_FmPortParams->specificParams.imRxTxParams.liodnOffset; 254296177Sjhibbits p_FmPort->im.dataMemId = p_FmPortParams->specificParams.imRxTxParams.dataMemId; 255296177Sjhibbits p_FmPort->im.dataMemAttributes = p_FmPortParams->specificParams.imRxTxParams.dataMemAttributes; 256296177Sjhibbits 257296177Sjhibbits p_FmPort->im.fwExtStructsMemId = DEFAULT_PORT_ImfwExtStructsMemId; 258296177Sjhibbits p_FmPort->im.fwExtStructsMemAttr = DEFAULT_PORT_ImfwExtStructsMemAttr; 259296177Sjhibbits 260296177Sjhibbits if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) || 261296177Sjhibbits (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) 262296177Sjhibbits { 263296177Sjhibbits p_FmPort->im.rxPool.h_BufferPool = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.h_BufferPool; 264296177Sjhibbits p_FmPort->im.rxPool.f_GetBuf = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.f_GetBuf; 265296177Sjhibbits p_FmPort->im.rxPool.f_PutBuf = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.f_PutBuf; 266296177Sjhibbits p_FmPort->im.rxPool.bufferSize = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.bufferSize; 267296177Sjhibbits p_FmPort->im.rxPool.f_PhysToVirt = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.f_PhysToVirt; 268296177Sjhibbits if (!p_FmPort->im.rxPool.f_PhysToVirt) 269296177Sjhibbits p_FmPort->im.rxPool.f_PhysToVirt = XX_PhysToVirt; 270296177Sjhibbits p_FmPort->im.rxPool.f_VirtToPhys = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.f_VirtToPhys; 271296177Sjhibbits if (!p_FmPort->im.rxPool.f_VirtToPhys) 272296177Sjhibbits p_FmPort->im.rxPool.f_VirtToPhys = XX_VirtToPhys; 273296177Sjhibbits p_FmPort->im.f_RxStore = p_FmPortParams->specificParams.imRxTxParams.f_RxStore; 274296177Sjhibbits 275296177Sjhibbits p_FmPort->im.mrblr = 0x8000; 276296177Sjhibbits while (p_FmPort->im.mrblr) 277296177Sjhibbits { 278296177Sjhibbits if (p_FmPort->im.rxPool.bufferSize & p_FmPort->im.mrblr) 279296177Sjhibbits break; 280296177Sjhibbits p_FmPort->im.mrblr >>= 1; 281296177Sjhibbits } 282296177Sjhibbits if (p_FmPort->im.mrblr != p_FmPort->im.rxPool.bufferSize) 283296177Sjhibbits DBG(WARNING, ("Max-Rx-Buffer-Length set to %d", p_FmPort->im.mrblr)); 284296177Sjhibbits p_FmPort->im.bdRingSize = DEFAULT_PORT_rxBdRingLength; 285296177Sjhibbits p_FmPort->exceptions = DEFAULT_exception; 286296177Sjhibbits if (FmIsMaster(p_FmPort->h_Fm)) 287296177Sjhibbits p_FmPort->polling = FALSE; 288296177Sjhibbits else 289296177Sjhibbits p_FmPort->polling = TRUE; 290296177Sjhibbits p_FmPort->fmanCtrlEventId = (uint8_t)NO_IRQ; 291296177Sjhibbits } 292296177Sjhibbits else 293296177Sjhibbits { 294296177Sjhibbits p_FmPort->im.f_TxConf = p_FmPortParams->specificParams.imRxTxParams.f_TxConf; 295296177Sjhibbits 296296177Sjhibbits p_FmPort->im.bdRingSize = DEFAULT_PORT_txBdRingLength; 297296177Sjhibbits } 298296177Sjhibbits} 299296177Sjhibbits 300296177Sjhibbitst_Error FmPortImCheckInitParameters(t_FmPort *p_FmPort) 301296177Sjhibbits{ 302296177Sjhibbits if ((p_FmPort->portType != e_FM_PORT_TYPE_RX) && 303296177Sjhibbits (p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && 304296177Sjhibbits (p_FmPort->portType != e_FM_PORT_TYPE_TX) && 305296177Sjhibbits (p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)) 306296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); 307296177Sjhibbits 308296177Sjhibbits if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) || 309296177Sjhibbits (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) 310296177Sjhibbits { 311296177Sjhibbits if (!POWER_OF_2(p_FmPort->im.mrblr)) 312296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("max Rx buffer length must be power of 2!!!")); 313296177Sjhibbits if (p_FmPort->im.mrblr < 256) 314296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("max Rx buffer length must at least 256!!!")); 315296177Sjhibbits if(p_FmPort->p_FmPortDriverParam->liodnOffset & ~FM_LIODN_OFFSET_MASK) 316296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("liodnOffset is larger than %d", FM_LIODN_OFFSET_MASK+1)); 317296177Sjhibbits#ifdef FM_PARTITION_ARRAY 318296177Sjhibbits { 319296177Sjhibbits t_FmRevisionInfo revInfo; 320296177Sjhibbits FM_GetRevision(p_FmPort->h_Fm, &revInfo); 321296177Sjhibbits if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0)) 322296177Sjhibbits { 323296177Sjhibbits if(p_FmPort->p_FmPortDriverParam->liodnOffset >= MAX_LIODN_OFFSET) 324296177Sjhibbits { 325296177Sjhibbits p_FmPort->p_FmPortDriverParam->liodnOffset = 326296177Sjhibbits (uint16_t)(p_FmPort->p_FmPortDriverParam->liodnOffset & (MAX_LIODN_OFFSET-1)); 327296177Sjhibbits DBG(WARNING, ("liodnOffset number is out of rev1 range - MSB bits cleard.")); 328296177Sjhibbits } 329296177Sjhibbits } 330296177Sjhibbits } 331296177Sjhibbits#endif /* FM_PARTITION_ARRAY */ 332296177Sjhibbits/* TODO - add checks */ 333296177Sjhibbits } 334296177Sjhibbits else 335296177Sjhibbits { 336296177Sjhibbits/* TODO - add checks */ 337296177Sjhibbits } 338296177Sjhibbits 339296177Sjhibbits return E_OK; 340296177Sjhibbits} 341296177Sjhibbits 342296177Sjhibbitst_Error FmPortImInit(t_FmPort *p_FmPort) 343296177Sjhibbits{ 344296177Sjhibbits t_FmImBd *p_Bd=NULL; 345296177Sjhibbits t_Handle h_BufContext; 346296177Sjhibbits uint64_t tmpPhysBase; 347296177Sjhibbits uint16_t log2Num; 348296177Sjhibbits uint8_t *p_Data/*, *p_Tmp*/; 349296177Sjhibbits int i; 350296177Sjhibbits t_Error err; 351296177Sjhibbits uint16_t tmpReg16; 352296177Sjhibbits uint32_t tmpReg32; 353296177Sjhibbits 354296177Sjhibbits ASSERT_COND(p_FmPort); 355296177Sjhibbits 356296177Sjhibbits p_FmPort->im.p_FmPortImPram = 357296177Sjhibbits (t_FmPortImPram *)FM_MURAM_AllocMem(p_FmPort->im.h_FmMuram, sizeof(t_FmPortImPram), IM_PRAM_ALIGN); 358296177Sjhibbits if (!p_FmPort->im.p_FmPortImPram) 359296177Sjhibbits RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Parameter-RAM!!!")); 360296177Sjhibbits WRITE_BLOCK(p_FmPort->im.p_FmPortImPram, 0, sizeof(t_FmPortImPram)); 361296177Sjhibbits 362296177Sjhibbits if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) || 363296177Sjhibbits (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) 364296177Sjhibbits { 365296177Sjhibbits p_FmPort->im.p_BdRing = (t_FmImBd *)XX_MallocSmart((uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize), p_FmPort->im.fwExtStructsMemId, 4); 366296177Sjhibbits if (!p_FmPort->im.p_BdRing) 367296177Sjhibbits RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Rx BD ring!!!")); 368296177Sjhibbits IOMemSet32(p_FmPort->im.p_BdRing, 0, (uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize)); 369296177Sjhibbits 370296177Sjhibbits p_FmPort->im.p_BdShadow = (t_Handle *)XX_Malloc((uint32_t)(sizeof(t_Handle)*p_FmPort->im.bdRingSize)); 371296177Sjhibbits if (!p_FmPort->im.p_BdShadow) 372296177Sjhibbits RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Rx BD shadow!!!")); 373296177Sjhibbits memset(p_FmPort->im.p_BdShadow, 0, (uint32_t)(sizeof(t_Handle)*p_FmPort->im.bdRingSize)); 374296177Sjhibbits 375296177Sjhibbits /* Initialize the Rx-BD ring */ 376296177Sjhibbits for (i=0; i<p_FmPort->im.bdRingSize; i++) 377296177Sjhibbits { 378296177Sjhibbits p_Bd = BD_GET(i); 379296177Sjhibbits BD_STATUS_AND_LENGTH_SET (p_Bd, BD_R_E); 380296177Sjhibbits 381296177Sjhibbits if ((p_Data = p_FmPort->im.rxPool.f_GetBuf(p_FmPort->im.rxPool.h_BufferPool, &h_BufContext)) == NULL) 382296177Sjhibbits RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Data buffer")); 383296177Sjhibbits BdBufferSet(p_FmPort->im.rxPool.f_VirtToPhys, p_Bd, p_Data); 384296177Sjhibbits p_FmPort->im.p_BdShadow[i] = h_BufContext; 385296177Sjhibbits } 386296177Sjhibbits 387296177Sjhibbits if ((p_FmPort->im.dataMemAttributes & MEMORY_ATTR_CACHEABLE) || 388296177Sjhibbits (p_FmPort->im.fwExtStructsMemAttr & MEMORY_ATTR_CACHEABLE)) 389296177Sjhibbits WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, IM_MODE_GBL | IM_MODE_SET_BO(2)); 390296177Sjhibbits else 391296177Sjhibbits WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, IM_MODE_SET_BO(2)); 392296177Sjhibbits 393296177Sjhibbits WRITE_UINT32(p_FmPort->im.p_FmPortImPram->rxQdPtr, 394296177Sjhibbits (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) - 395296177Sjhibbits p_FmPort->p_FmPortDriverParam->fmMuramPhysBaseAddr + 0x20)); 396296177Sjhibbits 397296177Sjhibbits LOG2((uint64_t)p_FmPort->im.mrblr, log2Num); 398296177Sjhibbits WRITE_UINT16(p_FmPort->im.p_FmPortImPram->mrblr, log2Num); 399296177Sjhibbits 400296177Sjhibbits /* Initialize Rx QD */ 401296177Sjhibbits tmpPhysBase = (uint64_t)(XX_VirtToPhys(p_FmPort->im.p_BdRing)); 402296177Sjhibbits SET_ADDR(&p_FmPort->im.p_FmPortImPram->rxQd.bdRingBase, tmpPhysBase); 403296177Sjhibbits WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.bdRingSize, (uint16_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize)); 404296177Sjhibbits 405296177Sjhibbits /* Update the IM PRAM address in the BMI */ 406296177Sjhibbits WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfqid, 407296177Sjhibbits (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) - 408296177Sjhibbits p_FmPort->p_FmPortDriverParam->fmMuramPhysBaseAddr)); 409296177Sjhibbits if (!p_FmPort->polling || p_FmPort->exceptions) 410296177Sjhibbits { 411296177Sjhibbits /* Allocate, configure and register interrupts */ 412296177Sjhibbits err = FmAllocFmanCtrlEventReg(p_FmPort->h_Fm, &p_FmPort->fmanCtrlEventId); 413296177Sjhibbits if(err) 414296177Sjhibbits RETURN_ERROR(MAJOR, err, NO_MSG); 415296177Sjhibbits 416296177Sjhibbits ASSERT_COND(!(p_FmPort->fmanCtrlEventId & ~IM_RXQD_FPMEVT_SEL_MASK)); 417296177Sjhibbits tmpReg16 = (uint16_t)(p_FmPort->fmanCtrlEventId & IM_RXQD_FPMEVT_SEL_MASK); 418296177Sjhibbits tmpReg32 = 0; 419296177Sjhibbits 420296177Sjhibbits if(p_FmPort->exceptions & IM_EV_BSY) 421296177Sjhibbits { 422296177Sjhibbits tmpReg16 |= IM_RXQD_BSYINTM; 423296177Sjhibbits tmpReg32 |= IM_EV_BSY; 424296177Sjhibbits } 425296177Sjhibbits if(!p_FmPort->polling) 426296177Sjhibbits { 427296177Sjhibbits tmpReg16 |= IM_RXQD_RXFINTM; 428296177Sjhibbits tmpReg32 |= IM_EV_RX; 429296177Sjhibbits } 430296177Sjhibbits WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, tmpReg16); 431296177Sjhibbits 432296177Sjhibbits FmRegisterFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, ImException , (t_Handle)p_FmPort); 433296177Sjhibbits 434296177Sjhibbits FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, tmpReg32); 435296177Sjhibbits } 436296177Sjhibbits else 437296177Sjhibbits p_FmPort->fmanCtrlEventId = (uint8_t)NO_IRQ; 438296177Sjhibbits } 439296177Sjhibbits else 440296177Sjhibbits { 441296177Sjhibbits p_FmPort->im.p_BdRing = (t_FmImBd *)XX_MallocSmart((uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize), p_FmPort->im.fwExtStructsMemId, 4); 442296177Sjhibbits if (!p_FmPort->im.p_BdRing) 443296177Sjhibbits RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Tx BD ring!!!")); 444296177Sjhibbits IOMemSet32(p_FmPort->im.p_BdRing, 0, (uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize)); 445296177Sjhibbits 446296177Sjhibbits p_FmPort->im.p_BdShadow = (t_Handle *)XX_Malloc((uint32_t)(sizeof(t_Handle)*p_FmPort->im.bdRingSize)); 447296177Sjhibbits if (!p_FmPort->im.p_BdShadow) 448296177Sjhibbits RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Rx BD shadow!!!")); 449296177Sjhibbits memset(p_FmPort->im.p_BdShadow, 0, (uint32_t)(sizeof(t_Handle)*p_FmPort->im.bdRingSize)); 450296177Sjhibbits p_FmPort->im.firstBdOfFrameId = IM_ILEGAL_BD_ID; 451296177Sjhibbits 452296177Sjhibbits if ((p_FmPort->im.dataMemAttributes & MEMORY_ATTR_CACHEABLE) || 453296177Sjhibbits (p_FmPort->im.fwExtStructsMemAttr & MEMORY_ATTR_CACHEABLE)) 454296177Sjhibbits WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, IM_MODE_GBL | IM_MODE_SET_BO(2)); 455296177Sjhibbits else 456296177Sjhibbits WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, IM_MODE_SET_BO(2)); 457296177Sjhibbits 458296177Sjhibbits WRITE_UINT32(p_FmPort->im.p_FmPortImPram->txQdPtr, 459296177Sjhibbits (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) - 460296177Sjhibbits p_FmPort->p_FmPortDriverParam->fmMuramPhysBaseAddr + 0x40)); 461296177Sjhibbits 462296177Sjhibbits /* Initialize Tx QD */ 463296177Sjhibbits tmpPhysBase = (uint64_t)(XX_VirtToPhys(p_FmPort->im.p_BdRing)); 464296177Sjhibbits SET_ADDR(&p_FmPort->im.p_FmPortImPram->txQd.bdRingBase, tmpPhysBase); 465296177Sjhibbits WRITE_UINT16(p_FmPort->im.p_FmPortImPram->txQd.bdRingSize, (uint16_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize)); 466296177Sjhibbits 467296177Sjhibbits /* Update the IM PRAM address in the BMI */ 468296177Sjhibbits WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfqid, 469296177Sjhibbits (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) - 470296177Sjhibbits p_FmPort->p_FmPortDriverParam->fmMuramPhysBaseAddr)); 471296177Sjhibbits } 472296177Sjhibbits 473296177Sjhibbits 474296177Sjhibbits return E_OK; 475296177Sjhibbits} 476296177Sjhibbits 477296177Sjhibbitsvoid FmPortImFree(t_FmPort *p_FmPort) 478296177Sjhibbits{ 479296177Sjhibbits uint32_t bdStatus; 480296177Sjhibbits uint8_t *p_CurData; 481296177Sjhibbits 482296177Sjhibbits ASSERT_COND(p_FmPort); 483296177Sjhibbits ASSERT_COND(p_FmPort->im.p_FmPortImPram); 484296177Sjhibbits 485296177Sjhibbits if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) || 486296177Sjhibbits (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) 487296177Sjhibbits { 488296177Sjhibbits if (!p_FmPort->polling || p_FmPort->exceptions) 489296177Sjhibbits { 490296177Sjhibbits /* Deallocate and unregister interrupts */ 491296177Sjhibbits FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, 0); 492296177Sjhibbits 493296177Sjhibbits FmFreeFmanCtrlEventReg(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId); 494296177Sjhibbits 495296177Sjhibbits WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, 0); 496296177Sjhibbits 497296177Sjhibbits FmUnregisterFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId); 498296177Sjhibbits } 499296177Sjhibbits /* Try first clean what has received */ 500296177Sjhibbits FmPortImRx(p_FmPort); 501296177Sjhibbits 502296177Sjhibbits /* Now, get rid of the the empty buffer! */ 503296177Sjhibbits bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId)); 504296177Sjhibbits 505296177Sjhibbits while (bdStatus & BD_R_E) /* while there is data in the Rx BD */ 506296177Sjhibbits { 507296177Sjhibbits p_CurData = BdBufferGet(p_FmPort->im.rxPool.f_PhysToVirt, BD_GET(p_FmPort->im.currBdId)); 508296177Sjhibbits 509296177Sjhibbits BdBufferSet(p_FmPort->im.rxPool.f_VirtToPhys, BD_GET(p_FmPort->im.currBdId), NULL); 510296177Sjhibbits BD_STATUS_AND_LENGTH_SET(BD_GET(p_FmPort->im.currBdId), 0); 511296177Sjhibbits 512296177Sjhibbits p_FmPort->im.rxPool.f_PutBuf(p_FmPort->im.rxPool.h_BufferPool, 513296177Sjhibbits p_CurData, 514296177Sjhibbits p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId]); 515296177Sjhibbits 516296177Sjhibbits p_FmPort->im.currBdId = GetNextBdId(p_FmPort, p_FmPort->im.currBdId); 517296177Sjhibbits bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId)); 518296177Sjhibbits } 519296177Sjhibbits } 520296177Sjhibbits else 521296177Sjhibbits TxConf(p_FmPort, e_TX_CONF_TYPE_FLUSH); 522296177Sjhibbits 523296177Sjhibbits FM_MURAM_FreeMem(p_FmPort->im.h_FmMuram, p_FmPort->im.p_FmPortImPram); 524296177Sjhibbits 525296177Sjhibbits if (p_FmPort->im.p_BdShadow) 526296177Sjhibbits XX_Free(p_FmPort->im.p_BdShadow); 527296177Sjhibbits 528296177Sjhibbits if (p_FmPort->im.p_BdRing) 529296177Sjhibbits XX_FreeSmart(p_FmPort->im.p_BdRing); 530296177Sjhibbits} 531296177Sjhibbits 532296177Sjhibbits 533296177Sjhibbitst_Error FM_PORT_ConfigIMMaxRxBufLength(t_Handle h_FmPort, uint16_t newVal) 534296177Sjhibbits{ 535296177Sjhibbits t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 536296177Sjhibbits 537296177Sjhibbits SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 538296177Sjhibbits SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE); 539296177Sjhibbits SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 540296177Sjhibbits 541296177Sjhibbits p_FmPort->im.mrblr = newVal; 542296177Sjhibbits 543296177Sjhibbits return E_OK; 544296177Sjhibbits} 545296177Sjhibbits 546296177Sjhibbitst_Error FM_PORT_ConfigIMRxBdRingLength(t_Handle h_FmPort, uint16_t newVal) 547296177Sjhibbits{ 548296177Sjhibbits t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 549296177Sjhibbits 550296177Sjhibbits SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 551296177Sjhibbits SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE); 552296177Sjhibbits SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 553296177Sjhibbits 554296177Sjhibbits p_FmPort->im.bdRingSize = newVal; 555296177Sjhibbits 556296177Sjhibbits return E_OK; 557296177Sjhibbits} 558296177Sjhibbits 559296177Sjhibbitst_Error FM_PORT_ConfigIMTxBdRingLength(t_Handle h_FmPort, uint16_t newVal) 560296177Sjhibbits{ 561296177Sjhibbits t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 562296177Sjhibbits 563296177Sjhibbits SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 564296177Sjhibbits SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE); 565296177Sjhibbits SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 566296177Sjhibbits 567296177Sjhibbits p_FmPort->im.bdRingSize = newVal; 568296177Sjhibbits 569296177Sjhibbits return E_OK; 570296177Sjhibbits} 571296177Sjhibbits 572296177Sjhibbitst_Error FM_PORT_ConfigIMFmanCtrlExternalStructsMemory(t_Handle h_FmPort, 573296177Sjhibbits uint8_t memId, 574296177Sjhibbits uint32_t memAttributes) 575296177Sjhibbits{ 576296177Sjhibbits t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 577296177Sjhibbits 578296177Sjhibbits SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 579296177Sjhibbits SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE); 580296177Sjhibbits SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 581296177Sjhibbits 582296177Sjhibbits p_FmPort->im.fwExtStructsMemId = memId; 583296177Sjhibbits p_FmPort->im.fwExtStructsMemAttr = memAttributes; 584296177Sjhibbits 585296177Sjhibbits return E_OK; 586296177Sjhibbits} 587296177Sjhibbits 588296177Sjhibbitst_Error FM_PORT_ConfigIMPolling(t_Handle h_FmPort) 589296177Sjhibbits{ 590296177Sjhibbits t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 591296177Sjhibbits 592296177Sjhibbits SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 593296177Sjhibbits SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE); 594296177Sjhibbits SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 595296177Sjhibbits 596296177Sjhibbits if((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) 597296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Available for Rx ports only")); 598296177Sjhibbits 599296177Sjhibbits if (!FmIsMaster(p_FmPort->h_Fm)) 600296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Available on master-partition only;" 601296177Sjhibbits "in guest-partitions, IM is always in polling!")); 602296177Sjhibbits 603296177Sjhibbits p_FmPort->polling = TRUE; 604296177Sjhibbits 605296177Sjhibbits return E_OK; 606296177Sjhibbits} 607296177Sjhibbits 608296177Sjhibbitst_Error FM_PORT_SetIMExceptions(t_Handle h_FmPort, e_FmPortExceptions exception, bool enable) 609296177Sjhibbits{ 610296177Sjhibbits t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 611296177Sjhibbits t_Error err; 612296177Sjhibbits uint16_t tmpReg16; 613296177Sjhibbits uint32_t tmpReg32; 614296177Sjhibbits 615296177Sjhibbits SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 616296177Sjhibbits SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE); 617296177Sjhibbits SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 618296177Sjhibbits 619296177Sjhibbits if(exception == e_FM_PORT_EXCEPTION_IM_BUSY) 620296177Sjhibbits { 621296177Sjhibbits if(enable) 622296177Sjhibbits { 623296177Sjhibbits p_FmPort->exceptions |= IM_EV_BSY; 624296177Sjhibbits if(p_FmPort->fmanCtrlEventId == (uint8_t)NO_IRQ) 625296177Sjhibbits { 626296177Sjhibbits /* Allocate, configure and register interrupts */ 627296177Sjhibbits err = FmAllocFmanCtrlEventReg(p_FmPort->h_Fm, &p_FmPort->fmanCtrlEventId); 628296177Sjhibbits if(err) 629296177Sjhibbits RETURN_ERROR(MAJOR, err, NO_MSG); 630296177Sjhibbits ASSERT_COND(!(p_FmPort->fmanCtrlEventId & ~IM_RXQD_FPMEVT_SEL_MASK)); 631296177Sjhibbits 632296177Sjhibbits FmRegisterFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, ImException, (t_Handle)p_FmPort); 633296177Sjhibbits tmpReg16 = (uint16_t)((p_FmPort->fmanCtrlEventId & IM_RXQD_FPMEVT_SEL_MASK) | IM_RXQD_BSYINTM); 634296177Sjhibbits tmpReg32 = IM_EV_BSY; 635296177Sjhibbits } 636296177Sjhibbits else 637296177Sjhibbits { 638296177Sjhibbits tmpReg16 = (uint16_t)(GET_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen) | IM_RXQD_BSYINTM); 639296177Sjhibbits tmpReg32 = FmGetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId) | IM_EV_BSY; 640296177Sjhibbits } 641296177Sjhibbits 642296177Sjhibbits WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, tmpReg16); 643296177Sjhibbits FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, tmpReg32); 644296177Sjhibbits } 645296177Sjhibbits else 646296177Sjhibbits { 647296177Sjhibbits p_FmPort->exceptions &= ~IM_EV_BSY; 648296177Sjhibbits if (!p_FmPort->exceptions && p_FmPort->polling) 649296177Sjhibbits { 650296177Sjhibbits FmFreeFmanCtrlEventReg(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId); 651296177Sjhibbits FmUnregisterFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId); 652296177Sjhibbits FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, 0); 653296177Sjhibbits WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, 0); 654296177Sjhibbits p_FmPort->fmanCtrlEventId = (uint8_t)NO_IRQ; 655296177Sjhibbits } 656296177Sjhibbits else 657296177Sjhibbits { 658296177Sjhibbits tmpReg16 = (uint16_t)(GET_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen) & ~IM_RXQD_BSYINTM); 659296177Sjhibbits WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, tmpReg16); 660296177Sjhibbits tmpReg32 = FmGetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId) & ~IM_EV_BSY; 661296177Sjhibbits FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, tmpReg32); 662296177Sjhibbits } 663296177Sjhibbits } 664296177Sjhibbits } 665296177Sjhibbits else 666296177Sjhibbits RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("Invalid exception.")); 667296177Sjhibbits 668296177Sjhibbits return E_OK; 669296177Sjhibbits} 670296177Sjhibbits 671296177Sjhibbitst_Error FM_PORT_ImTx( t_Handle h_FmPort, 672296177Sjhibbits uint8_t *p_Data, 673296177Sjhibbits uint16_t length, 674296177Sjhibbits bool lastBuffer, 675296177Sjhibbits t_Handle h_BufContext) 676296177Sjhibbits{ 677296177Sjhibbits t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 678296177Sjhibbits uint16_t nextBdId; 679296177Sjhibbits uint32_t bdStatus, nextBdStatus; 680296177Sjhibbits bool firstBuffer; 681296177Sjhibbits 682296177Sjhibbits SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 683296177Sjhibbits SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE); 684296177Sjhibbits SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 685296177Sjhibbits 686296177Sjhibbits bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId)); 687296177Sjhibbits nextBdId = GetNextBdId(p_FmPort, p_FmPort->im.currBdId); 688296177Sjhibbits nextBdStatus = BD_STATUS_AND_LENGTH(BD_GET(nextBdId)); 689296177Sjhibbits 690296177Sjhibbits if (!(bdStatus & BD_R_E) && !(nextBdStatus & BD_R_E)) 691296177Sjhibbits { 692296177Sjhibbits /* Confirm the current BD - BD is available */ 693296177Sjhibbits if ((bdStatus & BD_LENGTH_MASK) && (p_FmPort->im.f_TxConf)) 694296177Sjhibbits p_FmPort->im.f_TxConf (p_FmPort->h_App, 695296177Sjhibbits BdBufferGet(XX_PhysToVirt, BD_GET(p_FmPort->im.currBdId)), 696296177Sjhibbits 0, 697296177Sjhibbits p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId]); 698296177Sjhibbits 699296177Sjhibbits bdStatus = length; 700296177Sjhibbits 701296177Sjhibbits /* if this is the first BD of a frame */ 702296177Sjhibbits if (p_FmPort->im.firstBdOfFrameId == IM_ILEGAL_BD_ID) 703296177Sjhibbits { 704296177Sjhibbits firstBuffer = TRUE; 705296177Sjhibbits p_FmPort->im.txFirstBdStatus = (bdStatus | BD_R_E); 706296177Sjhibbits 707296177Sjhibbits if (!lastBuffer) 708296177Sjhibbits p_FmPort->im.firstBdOfFrameId = p_FmPort->im.currBdId; 709296177Sjhibbits } 710296177Sjhibbits else 711296177Sjhibbits firstBuffer = FALSE; 712296177Sjhibbits 713296177Sjhibbits BdBufferSet(XX_VirtToPhys, BD_GET(p_FmPort->im.currBdId), p_Data); 714296177Sjhibbits p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId] = h_BufContext; 715296177Sjhibbits 716296177Sjhibbits /* deal with last */ 717296177Sjhibbits if (lastBuffer) 718296177Sjhibbits { 719296177Sjhibbits /* if single buffer frame */ 720296177Sjhibbits if (firstBuffer) 721296177Sjhibbits BD_STATUS_AND_LENGTH_SET(BD_GET(p_FmPort->im.currBdId), p_FmPort->im.txFirstBdStatus | BD_L); 722296177Sjhibbits else 723296177Sjhibbits { 724296177Sjhibbits /* Set the last BD of the frame */ 725296177Sjhibbits BD_STATUS_AND_LENGTH_SET (BD_GET(p_FmPort->im.currBdId), (bdStatus | BD_R_E | BD_L)); 726296177Sjhibbits /* Set the first BD of the frame */ 727296177Sjhibbits BD_STATUS_AND_LENGTH_SET(BD_GET(p_FmPort->im.firstBdOfFrameId), p_FmPort->im.txFirstBdStatus); 728296177Sjhibbits p_FmPort->im.firstBdOfFrameId = IM_ILEGAL_BD_ID; 729296177Sjhibbits } 730296177Sjhibbits WRITE_UINT16(p_FmPort->im.p_FmPortImPram->txQd.offsetIn, (uint16_t)(GetNextBdId(p_FmPort, p_FmPort->im.currBdId)<<4)); 731296177Sjhibbits } 732296177Sjhibbits else if (!firstBuffer) /* mid frame buffer */ 733296177Sjhibbits BD_STATUS_AND_LENGTH_SET (BD_GET(p_FmPort->im.currBdId), bdStatus | BD_R_E); 734296177Sjhibbits 735296177Sjhibbits p_FmPort->im.currBdId = GetNextBdId(p_FmPort, p_FmPort->im.currBdId); 736296177Sjhibbits } 737296177Sjhibbits else 738296177Sjhibbits { 739296177Sjhibbits /* Discard current frame. Return error. */ 740296177Sjhibbits if (p_FmPort->im.firstBdOfFrameId != IM_ILEGAL_BD_ID) 741296177Sjhibbits { 742296177Sjhibbits /* Error: No free BD */ 743296177Sjhibbits /* Response: Discard current frame. Return error. */ 744296177Sjhibbits uint16_t cleanBdId = p_FmPort->im.firstBdOfFrameId; 745296177Sjhibbits 746296177Sjhibbits ASSERT_COND(p_FmPort->im.firstBdOfFrameId != p_FmPort->im.currBdId); 747296177Sjhibbits 748296177Sjhibbits /* Since firstInFrame is not NULL, one buffer at least has already been 749296177Sjhibbits inserted into the BD ring. Using do-while covers the situation of a 750296177Sjhibbits frame spanned throughout the whole Tx BD ring (p_CleanBd is incremented 751296177Sjhibbits prior to testing whether or not it's equal to TxBd). */ 752296177Sjhibbits do 753296177Sjhibbits { 754296177Sjhibbits BD_STATUS_AND_LENGTH_SET(BD_GET(cleanBdId), 0); 755296177Sjhibbits /* Advance BD pointer */ 756296177Sjhibbits cleanBdId = GetNextBdId(p_FmPort, cleanBdId); 757296177Sjhibbits } while (cleanBdId != p_FmPort->im.currBdId); 758296177Sjhibbits 759296177Sjhibbits p_FmPort->im.currBdId = cleanBdId; 760296177Sjhibbits p_FmPort->im.firstBdOfFrameId = IM_ILEGAL_BD_ID; 761296177Sjhibbits } 762296177Sjhibbits 763296177Sjhibbits return ERROR_CODE(E_FULL); 764296177Sjhibbits } 765296177Sjhibbits 766296177Sjhibbits return E_OK; 767296177Sjhibbits} 768296177Sjhibbits 769296177Sjhibbitsvoid FM_PORT_ImTxConf(t_Handle h_FmPort) 770296177Sjhibbits{ 771296177Sjhibbits t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 772296177Sjhibbits 773296177Sjhibbits SANITY_CHECK_RETURN(p_FmPort, E_INVALID_HANDLE); 774296177Sjhibbits SANITY_CHECK_RETURN(p_FmPort->imEn, E_INVALID_STATE); 775296177Sjhibbits SANITY_CHECK_RETURN(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 776296177Sjhibbits 777296177Sjhibbits TxConf(p_FmPort, e_TX_CONF_TYPE_CALLBACK); 778296177Sjhibbits} 779296177Sjhibbits 780296177Sjhibbitst_Error FM_PORT_ImRx(t_Handle h_FmPort) 781296177Sjhibbits{ 782296177Sjhibbits t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 783296177Sjhibbits 784296177Sjhibbits SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 785296177Sjhibbits SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE); 786296177Sjhibbits SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 787296177Sjhibbits 788296177Sjhibbits return FmPortImRx(p_FmPort); 789296177Sjhibbits} 790