1 /* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. 2 * All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * * Redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer. 8 * * Redistributions in binary form must reproduce the above copyright 9 * notice, this list of conditions and the following disclaimer in the 10 * documentation and/or other materials provided with the distribution. 11 * * Neither the name of Freescale Semiconductor nor the 12 * names of its contributors may be used to endorse or promote products 13 * derived from this software without specific prior written permission. 14 * 15 * 16 * ALTERNATIVELY, this software may be distributed under the terms of the 17 * GNU General Public License ("GPL") as published by the Free Software 18 * Foundation, either version 2 of that License or (at your option) any 19 * later version. 20 * 21 * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY 22 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY 25 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 28 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 /****************************************************************************** 34 @File dtsec.c 35 36 @Description FM dTSEC ... 37 *//***************************************************************************/ 38 39 #include "std_ext.h" 40 #include "error_ext.h" 41 #include "string_ext.h" 42 #include "xx_ext.h" 43 #include "endian_ext.h" 44 #include "crc_mac_addr_ext.h" 45 #include "debug_ext.h" 46 47 #include "fm_common.h" 48 #include "dtsec.h" 49 50 51 /*****************************************************************************/ 52 /* Internal routines */ 53 /*****************************************************************************/ 54 55 static t_Error CheckInitParameters(t_Dtsec *p_Dtsec) 56 { 57 if(ENET_SPEED_FROM_MODE(p_Dtsec->enetMode) >= e_ENET_SPEED_10000) 58 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet 1G MAC driver only supports 1G or lower speeds")); 59 if(p_Dtsec->macId >= FM_MAX_NUM_OF_1G_MACS) 60 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("macId can not be greater than the number of 1G MACs")); 61 if(p_Dtsec->addr == 0) 62 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet MAC Must have a valid MAC Address")); 63 if(((p_Dtsec->enetMode == e_ENET_MODE_SGMII_1000) || 64 (p_Dtsec->enetMode == e_ENET_MODE_RGMII_1000) || 65 (p_Dtsec->enetMode == e_ENET_MODE_QSGMII_1000)) && 66 p_Dtsec->p_DtsecDriverParam->halfDuplex) 67 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet MAC 1G can't work in half duplex")); 68 if(p_Dtsec->p_DtsecDriverParam->halfDuplex && (p_Dtsec->p_DtsecDriverParam)->loopback) 69 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("LoopBack is not supported in halfDuplex mode")); 70 #ifdef FM_NO_RX_PREAM_ERRATA_DTSECx1 71 if(p_Dtsec->p_DtsecDriverParam->preambleRxEn) 72 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("preambleRxEn")); 73 #endif /* FM_NO_RX_PREAM_ERRATA_DTSECx1 */ 74 if(((p_Dtsec->p_DtsecDriverParam)->preambleTxEn || (p_Dtsec->p_DtsecDriverParam)->preambleRxEn) &&( (p_Dtsec->p_DtsecDriverParam)->preambleLength != 0x7)) 75 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Preamble length should be 0x7 bytes")); 76 if((p_Dtsec->p_DtsecDriverParam)->fifoTxWatermarkH<((p_Dtsec->p_DtsecDriverParam)->fifoTxThr+8)) 77 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fifoTxWatermarkH has to be at least 8 larger than fifoTxThr")); 78 if((p_Dtsec->p_DtsecDriverParam)->halfDuplex && 79 (p_Dtsec->p_DtsecDriverParam->txTimeStampEn || p_Dtsec->p_DtsecDriverParam->rxTimeStampEn)) 80 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dTSEC in half duplex mode has to be with 1588 timeStamping diable")); 81 if((p_Dtsec->p_DtsecDriverParam)->actOnRxPauseFrame && (p_Dtsec->p_DtsecDriverParam)->controlFrameAccept ) 82 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Receive control frame are not passed to the system memory so it can not be accept ")); 83 if((p_Dtsec->p_DtsecDriverParam)->packetAlignmentPadding > MAX_PACKET_ALIGNMENT) 84 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("packetAlignmentPadding can't be greater than %d ",MAX_PACKET_ALIGNMENT )); 85 if(((p_Dtsec->p_DtsecDriverParam)->nonBackToBackIpg1 > MAX_INTER_PACKET_GAP) || 86 ((p_Dtsec->p_DtsecDriverParam)->nonBackToBackIpg2 > MAX_INTER_PACKET_GAP) || 87 ((p_Dtsec->p_DtsecDriverParam)->backToBackIpg > MAX_INTER_PACKET_GAP)) 88 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inter packet gap can't be greater than %d ",MAX_INTER_PACKET_GAP )); 89 if((p_Dtsec->p_DtsecDriverParam)->alternateBackoffVal > MAX_INTER_PALTERNATE_BEB) 90 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("alternateBackoffVal can't be greater than %d ",MAX_INTER_PALTERNATE_BEB )); 91 if((p_Dtsec->p_DtsecDriverParam)->maxRetransmission > MAX_RETRANSMISSION) 92 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("maxRetransmission can't be greater than %d ",MAX_RETRANSMISSION )); 93 if((p_Dtsec->p_DtsecDriverParam)->collisionWindow > MAX_COLLISION_WINDOW) 94 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("collisionWindow can't be greater than %d ",MAX_COLLISION_WINDOW )); 95 96 /* If Auto negotiation process is disabled, need to */ 97 /* Set up the PHY using the MII Management Interface */ 98 if (p_Dtsec->p_DtsecDriverParam->tbiPhyAddr > MAX_PHYS) 99 RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, ("PHY address (should be 0-%d)", MAX_PHYS)); 100 if(!p_Dtsec->f_Exception) 101 RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("uninitialized f_Exception")); 102 if(!p_Dtsec->f_Event) 103 RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("uninitialized f_Event")); 104 return E_OK; 105 } 106 107 static uint8_t GetMiiDiv(int32_t refClk) 108 { 109 uint32_t div,tmpClk; 110 int minRange; 111 112 div = 1; 113 minRange = (int)(refClk/40 - 1); 114 115 tmpClk = (uint32_t)ABS(refClk/60 - 1); 116 if (tmpClk < minRange) 117 { 118 div = 2; 119 minRange = (int)tmpClk; 120 } 121 tmpClk = (uint32_t)ABS(refClk/60 - 1); 122 if (tmpClk < minRange) 123 { 124 div = 3; 125 minRange = (int)tmpClk; 126 } 127 tmpClk = (uint32_t)ABS(refClk/80 - 1); 128 if (tmpClk < minRange) 129 { 130 div = 4; 131 minRange = (int)tmpClk; 132 } 133 tmpClk = (uint32_t)ABS(refClk/100 - 1); 134 if (tmpClk < minRange) 135 { 136 div = 5; 137 minRange = (int)tmpClk; 138 } 139 tmpClk = (uint32_t)ABS(refClk/140 - 1); 140 if (tmpClk < minRange) 141 { 142 div = 6; 143 minRange = (int)tmpClk; 144 } 145 tmpClk = (uint32_t)ABS(refClk/280 - 1); 146 if (tmpClk < minRange) 147 { 148 div = 7; 149 minRange = (int)tmpClk; 150 } 151 152 return (uint8_t)div; 153 } 154 155 /* ........................................................................... */ 156 157 static void SetDefaultParam(t_DtsecDriverParam *p_DtsecDriverParam) 158 { 159 p_DtsecDriverParam->errorDisabled = DEFAULT_errorDisabled; 160 161 p_DtsecDriverParam->promiscuousEnable = DEFAULT_promiscuousEnable; 162 163 p_DtsecDriverParam->pauseExtended = DEFAULT_pauseExtended; 164 p_DtsecDriverParam->pauseTime = DEFAULT_pauseTime; 165 166 p_DtsecDriverParam->halfDuplex = DEFAULT_halfDuplex; 167 p_DtsecDriverParam->halfDulexFlowControlEn = DEFAULT_halfDulexFlowControlEn; 168 p_DtsecDriverParam->txTimeStampEn = DEFAULT_txTimeStampEn; 169 p_DtsecDriverParam->rxTimeStampEn = DEFAULT_rxTimeStampEn; 170 171 p_DtsecDriverParam->packetAlignmentPadding = DEFAULT_packetAlignment; 172 p_DtsecDriverParam->controlFrameAccept = DEFAULT_controlFrameAccept; 173 p_DtsecDriverParam->groupHashExtend = DEFAULT_groupHashExtend; 174 p_DtsecDriverParam->broadcReject = DEFAULT_broadcReject; 175 p_DtsecDriverParam->rxShortFrame = DEFAULT_rxShortFrame; 176 p_DtsecDriverParam->exactMatch = DEFAULT_exactMatch; 177 p_DtsecDriverParam->debugMode = DEFAULT_debugMode; 178 179 p_DtsecDriverParam->loopback = DEFAULT_loopback; 180 p_DtsecDriverParam->tbiPhyAddr = DEFAULT_tbiPhyAddr; 181 p_DtsecDriverParam->actOnRxPauseFrame = DEFAULT_actOnRxPauseFrame; 182 p_DtsecDriverParam->actOnTxPauseFrame = DEFAULT_actOnTxPauseFrame; 183 184 p_DtsecDriverParam->preambleLength = DEFAULT_PreAmLength; 185 p_DtsecDriverParam->preambleRxEn = DEFAULT_PreAmRxEn; 186 p_DtsecDriverParam->preambleTxEn = DEFAULT_PreAmTxEn; 187 p_DtsecDriverParam->lengthCheckEnable = DEFAULT_lengthCheckEnable; 188 p_DtsecDriverParam->padAndCrcEnable = DEFAULT_padAndCrcEnable; 189 p_DtsecDriverParam->crcEnable = DEFAULT_crcEnable; 190 191 p_DtsecDriverParam->nonBackToBackIpg1 = DEFAULT_nonBackToBackIpg1; 192 p_DtsecDriverParam->nonBackToBackIpg2 = DEFAULT_nonBackToBackIpg2; 193 p_DtsecDriverParam->minIfgEnforcement = DEFAULT_minIfgEnforcement; 194 p_DtsecDriverParam->backToBackIpg = DEFAULT_backToBackIpg; 195 196 p_DtsecDriverParam->alternateBackoffVal = DEFAULT_altBackoffVal; 197 p_DtsecDriverParam->alternateBackoffEnable = DEFAULT_altBackoffEnable; 198 p_DtsecDriverParam->backPressureNoBackoff = DEFAULT_backPressureNoBackoff; 199 p_DtsecDriverParam->noBackoff = DEFAULT_noBackoff; 200 p_DtsecDriverParam->excessDefer = DEFAULT_excessDefer; 201 p_DtsecDriverParam->maxRetransmission = DEFAULT_maxRetransmission; 202 p_DtsecDriverParam->collisionWindow = DEFAULT_collisionWindow; 203 204 p_DtsecDriverParam->maxFrameLength = DEFAULT_maxFrameLength; 205 206 p_DtsecDriverParam->fifoTxThr = DEFAULT_fifoTxThr; 207 p_DtsecDriverParam->fifoTxWatermarkH = DEFAULT_fifoTxWatermarkH; 208 209 p_DtsecDriverParam->fifoRxWatermarkL = DEFAULT_fifoRxWatermarkL; 210 } 211 212 static void DtsecException(t_Handle h_Dtsec) 213 { 214 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; 215 uint32_t event; 216 t_DtsecMemMap *p_DtsecMemMap; 217 218 ASSERT_COND(p_Dtsec); 219 p_DtsecMemMap = p_Dtsec->p_MemMap; 220 ASSERT_COND(p_DtsecMemMap); 221 222 event = GET_UINT32(p_DtsecMemMap->ievent); 223 /* handle only MDIO events */ 224 event &= (IMASK_MMRDEN | IMASK_MMWREN); 225 if(event) 226 { 227 event &= GET_UINT32(p_DtsecMemMap->imask); 228 229 WRITE_UINT32(p_DtsecMemMap->ievent, event); 230 231 if(event & IMASK_MMRDEN) 232 p_Dtsec->f_Event(p_Dtsec->h_App, e_FM_MAC_EX_1G_MII_MNG_RD_COMPLET); 233 if(event & IMASK_MMWREN) 234 p_Dtsec->f_Event(p_Dtsec->h_App, e_FM_MAC_EX_1G_MII_MNG_WR_COMPLET); 235 } 236 } 237 238 static void UpdateStatistics(t_Dtsec *p_Dtsec) 239 { 240 t_DtsecMemMap *p_DtsecMemMap = p_Dtsec->p_MemMap; 241 uint32_t car1 = GET_UINT32(p_DtsecMemMap->car1); 242 uint32_t car2 = GET_UINT32(p_DtsecMemMap->car2); 243 244 if(car1) 245 { 246 WRITE_UINT32(p_DtsecMemMap->car1, car1); 247 if(car1 & CAR1_TR64) 248 p_Dtsec->internalStatistics.tr64 += VAL22BIT; 249 if(car1 & CAR1_TR127) 250 p_Dtsec->internalStatistics.tr127 += VAL22BIT; 251 if(car1 & CAR1_TR255) 252 p_Dtsec->internalStatistics.tr255 += VAL22BIT; 253 if(car1 & CAR1_TR511) 254 p_Dtsec->internalStatistics.tr511 += VAL22BIT; 255 if(car1 & CAR1_TRK1) 256 p_Dtsec->internalStatistics.tr1k += VAL22BIT; 257 if(car1 & CAR1_TRMAX) 258 p_Dtsec->internalStatistics.trmax += VAL22BIT; 259 if(car1 & CAR1_TRMGV) 260 p_Dtsec->internalStatistics.trmgv += VAL22BIT; 261 if(car1 & CAR1_RBYT) 262 p_Dtsec->internalStatistics.rbyt += (uint64_t)VAL32BIT; 263 if(car1 & CAR1_RPKT) 264 p_Dtsec->internalStatistics.rpkt += VAL22BIT; 265 if(car1 & CAR1_RMCA) 266 p_Dtsec->internalStatistics.rmca += VAL22BIT; 267 if(car1 & CAR1_RBCA) 268 p_Dtsec->internalStatistics.rbca += VAL22BIT; 269 if(car1 & CAR1_RXPF) 270 p_Dtsec->internalStatistics.rxpf += VAL16BIT; 271 if(car1 & CAR1_RALN) 272 p_Dtsec->internalStatistics.raln += VAL16BIT; 273 if(car1 & CAR1_RFLR) 274 p_Dtsec->internalStatistics.rflr += VAL16BIT; 275 if(car1 & CAR1_RCDE) 276 p_Dtsec->internalStatistics.rcde += VAL16BIT; 277 if(car1 & CAR1_RCSE) 278 p_Dtsec->internalStatistics.rcse += VAL16BIT; 279 if(car1 & CAR1_RUND) 280 p_Dtsec->internalStatistics.rund += VAL16BIT; 281 if(car1 & CAR1_ROVR) 282 p_Dtsec->internalStatistics.rovr += VAL16BIT; 283 if(car1 & CAR1_RFRG) 284 p_Dtsec->internalStatistics.rfrg += VAL16BIT; 285 if(car1 & CAR1_RJBR) 286 p_Dtsec->internalStatistics.rjbr += VAL16BIT; 287 if(car1 & CAR1_RDRP) 288 p_Dtsec->internalStatistics.rdrp += VAL16BIT; 289 } 290 if(car2) 291 { 292 WRITE_UINT32(p_DtsecMemMap->car2, car2); 293 if(car2 & CAR2_TFCS) 294 p_Dtsec->internalStatistics.tfcs += VAL12BIT; 295 if(car2 & CAR2_TBYT) 296 p_Dtsec->internalStatistics.tbyt += (uint64_t)VAL32BIT; 297 if(car2 & CAR2_TPKT) 298 p_Dtsec->internalStatistics.tpkt += VAL22BIT; 299 if(car2 & CAR2_TMCA) 300 p_Dtsec->internalStatistics.tmca += VAL22BIT; 301 if(car2 & CAR2_TBCA) 302 p_Dtsec->internalStatistics.tbca += VAL22BIT; 303 if(car2 & CAR2_TXPF) 304 p_Dtsec->internalStatistics.txpf += VAL16BIT; 305 if(car2 & CAR2_TDRP) 306 p_Dtsec->internalStatistics.tdrp += VAL16BIT; 307 } 308 } 309 310 /* .............................................................................. */ 311 312 static uint16_t DtsecGetMaxFrameLength(t_Handle h_Dtsec) 313 { 314 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; 315 316 SANITY_CHECK_RETURN_VALUE(p_Dtsec, E_INVALID_HANDLE, 0); 317 318 return (uint16_t)GET_UINT32(p_Dtsec->p_MemMap->maxfrm); 319 } 320 321 static void DtsecErrException(t_Handle h_Dtsec) 322 { 323 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; 324 uint32_t event; 325 t_DtsecMemMap *p_DtsecMemMap = p_Dtsec->p_MemMap; 326 327 event = GET_UINT32(p_DtsecMemMap->ievent); 328 /* do not handle MDIO events */ 329 event &= ~(IMASK_MMRDEN | IMASK_MMWREN); 330 331 event &= GET_UINT32(p_DtsecMemMap->imask); 332 333 WRITE_UINT32(p_DtsecMemMap->ievent, event); 334 335 if(event & IMASK_BREN) 336 p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_BAB_RX); 337 if(event & IMASK_RXCEN) 338 p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_RX_CTL); 339 if(event & IMASK_MSROEN) 340 UpdateStatistics(p_Dtsec); 341 if(event & IMASK_GTSCEN) 342 p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET); 343 if(event & IMASK_BTEN) 344 p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_BAB_TX); 345 if(event & IMASK_TXCEN) 346 p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_CTL); 347 if(event & IMASK_TXEEN) 348 p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_ERR); 349 if(event & IMASK_LCEN) 350 p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_LATE_COL); 351 if(event & IMASK_CRLEN) 352 p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_COL_RET_LMT); 353 if(event & IMASK_XFUNEN) 354 { 355 #ifdef FM_TX_LOCKUP_ERRATA_DTSEC6 356 uint32_t tpkt1, tmpReg1, tpkt2, tmpReg2, i; 357 /* a. Write 0x00E0_0C00 to DTSEC_ID */ 358 /* This is a read only regidter */ 359 360 /* b. Read and save the value of TPKT */ 361 tpkt1 = GET_UINT32(p_DtsecMemMap->tpkt); 362 363 /* c. Read the register at dTSEC address offset 0x32C */ 364 tmpReg1 = GET_UINT32(*(uint32_t*)((uint8_t*)p_DtsecMemMap + 0x32c)); 365 366 /* d. Compare bits [9:15] to bits [25:31] of the register at address offset 0x32C. */ 367 if((tmpReg1 & 0x007F0000) != (tmpReg1 & 0x0000007F)) 368 { 369 /* If they are not equal, save the value of this register and wait for at least 370 * MAXFRM*16 ns */ 371 XX_UDelay((uint32_t)(NCSW_MIN(DtsecGetMaxFrameLength(p_Dtsec)*16/1000, 1))); 372 } 373 374 /* e. Read and save TPKT again and read the register at dTSEC address offset 375 0x32C again*/ 376 tpkt2 = GET_UINT32(p_DtsecMemMap->tpkt); 377 tmpReg2 = GET_UINT32(*(uint32_t*)((uint8_t*)p_DtsecMemMap + 0x32c)); 378 379 /* f. Compare the value of TPKT saved in step b to value read in step e. Also 380 compare bits [9:15] of the register at offset 0x32C saved in step d to the value 381 of bits [9:15] saved in step e. If the two registers values are unchanged, then 382 the transmit portion of the dTSEC controller is locked up and the user should 383 proceed to the recover sequence. */ 384 if((tpkt1 == tpkt2) && ((tmpReg1 & 0x007F0000) == (tmpReg2 & 0x007F0000))) 385 { 386 /* recover sequence */ 387 388 /* a.Write a 1 to RCTRL[GRS]*/ 389 390 WRITE_UINT32(p_DtsecMemMap->rctrl, GET_UINT32(p_DtsecMemMap->rctrl) | RCTRL_GRS); 391 392 /* b.Wait until IEVENT[GRSC]=1, or at least 100 us has elapsed. */ 393 for(i = 0 ; i < 100 ; i++ ) 394 { 395 if(GET_UINT32(p_DtsecMemMap->ievent) & IMASK_GRSCEN) 396 break; 397 XX_UDelay(1); 398 } 399 if(GET_UINT32(p_DtsecMemMap->ievent) & IMASK_GRSCEN) 400 WRITE_UINT32(p_DtsecMemMap->ievent, IMASK_GRSCEN); 401 else 402 DBG(INFO,("Rx lockup due to dTSEC Tx lockup")); 403 404 405 /* c.Write a 1 to bit n of FM_RSTC (offset 0x0CC of FPM)*/ 406 FmResetMac(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MAC_1G, p_Dtsec->fmMacControllerDriver.macId); 407 408 /* d.Wait 4 Tx clocks (32 ns) */ 409 XX_UDelay(1); 410 411 /* e.Write a 0 to bit n of FM_RSTC. */ 412 /* cleared by FMAN */ 413 } 414 else 415 { 416 /* If either value has changed, the dTSEC controller is not locked up and the 417 controller should be allowed to proceed normally by writing the reset value 418 of 0x0824_0101 to DTSEC_ID. */ 419 /* Register is read only */ 420 } 421 #endif /* FM_TX_LOCKUP_ERRATA_DTSEC6 */ 422 423 p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_FIFO_UNDRN); 424 } 425 if(event & IMASK_MAGEN) 426 p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_MAG_PCKT); 427 if(event & IMASK_GRSCEN) 428 p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET); 429 if(event & IMASK_TDPEEN) 430 p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_DATA_ERR); 431 if(event & IMASK_RDPEEN) 432 p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_RX_DATA_ERR); 433 434 /* - masked interrupts */ 435 ASSERT_COND(!(event & IMASK_ABRTEN)); 436 ASSERT_COND(!(event & IMASK_IFERREN)); 437 } 438 439 static void Dtsec1588Exception(t_Handle h_Dtsec) 440 { 441 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; 442 uint32_t event; 443 t_DtsecMemMap *p_DtsecMemMap = p_Dtsec->p_MemMap; 444 445 if (p_Dtsec->ptpTsuEnabled) 446 { 447 event = GET_UINT32(p_DtsecMemMap->tmr_pevent); 448 event &= GET_UINT32(p_DtsecMemMap->tmr_pemask); 449 if(event) 450 { 451 WRITE_UINT32(p_DtsecMemMap->tmr_pevent, event); 452 ASSERT_COND(event & PEMASK_TSRE); 453 p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_1588_TS_RX_ERR); 454 } 455 } 456 } 457 458 /* ........................................................................... */ 459 460 static void FreeInitResources(t_Dtsec *p_Dtsec) 461 { 462 /*TODO - need to ask why with mdioIrq != 0*/ 463 if ((p_Dtsec->mdioIrq != 0) && (p_Dtsec->mdioIrq != NO_IRQ)) 464 { 465 XX_DisableIntr(p_Dtsec->mdioIrq); 466 XX_FreeIntr(p_Dtsec->mdioIrq); 467 } 468 else if (p_Dtsec->mdioIrq == 0) 469 FmUnregisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Dtsec->macId, e_FM_INTR_TYPE_NORMAL); 470 FmUnregisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Dtsec->macId, e_FM_INTR_TYPE_ERR); 471 FmUnregisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC_TMR, p_Dtsec->macId, e_FM_INTR_TYPE_NORMAL); 472 473 /* release the driver's group hash table */ 474 FreeHashTable(p_Dtsec->p_MulticastAddrHash); 475 p_Dtsec->p_MulticastAddrHash = NULL; 476 477 /* release the driver's individual hash table */ 478 FreeHashTable(p_Dtsec->p_UnicastAddrHash); 479 p_Dtsec->p_UnicastAddrHash = NULL; 480 } 481 482 /* ........................................................................... */ 483 484 static void HardwareClearAddrInPaddr(t_Dtsec *p_Dtsec, uint8_t paddrNum) 485 { 486 WRITE_UINT32(((t_DtsecMemMap*)p_Dtsec->p_MemMap)->macaddr[paddrNum].exact_match1, 0x0); 487 WRITE_UINT32(((t_DtsecMemMap*)p_Dtsec->p_MemMap)->macaddr[paddrNum].exact_match2, 0x0); 488 } 489 490 /* ........................................................................... */ 491 492 static void HardwareAddAddrInPaddr(t_Dtsec *p_Dtsec, uint64_t *p_Addr, uint8_t paddrNum) 493 { 494 uint32_t tmpReg32 = 0; 495 uint64_t addr = *p_Addr; 496 t_DtsecMemMap *p_DtsecMemMap = (t_DtsecMemMap*)p_Dtsec->p_MemMap; 497 498 tmpReg32 = (uint32_t)(addr); 499 SwapUint32P(&tmpReg32); 500 WRITE_UINT32(p_DtsecMemMap->macaddr[paddrNum].exact_match1, tmpReg32); 501 502 tmpReg32 = (uint32_t)(addr>>32); 503 SwapUint32P(&tmpReg32); 504 WRITE_UINT32(p_DtsecMemMap->macaddr[paddrNum].exact_match2, tmpReg32); 505 } 506 507 /* ........................................................................... */ 508 509 static t_Error GracefulStop(t_Dtsec *p_Dtsec, e_CommMode mode) 510 { 511 t_DtsecMemMap *p_MemMap; 512 513 ASSERT_COND(p_Dtsec); 514 515 p_MemMap= (t_DtsecMemMap*)(p_Dtsec->p_MemMap); 516 ASSERT_COND(p_MemMap); 517 518 /* Assert the graceful transmit stop bit */ 519 if (mode & e_COMM_MODE_RX) 520 WRITE_UINT32(p_MemMap->rctrl, 521 GET_UINT32(p_MemMap->rctrl) | RCTRL_GRS); 522 523 #ifdef FM_GRS_ERRATA_DTSEC_A002 524 XX_UDelay(100); 525 #endif /* FM_GRS_ERRATA_DTSEC_A002 */ 526 527 #ifdef FM_GTS_ERRATA_DTSEC_A004 528 DBG(INFO, ("GTS not supported due to DTSEC_A004 errata.")); 529 #else /* not FM_GTS_ERRATA_DTSEC_A004 */ 530 if (mode & e_COMM_MODE_TX) 531 WRITE_UINT32(p_MemMap->tctrl, 532 GET_UINT32(p_MemMap->tctrl) | TCTRL_GTS); 533 #endif /* not FM_GTS_ERRATA_DTSEC_A004 */ 534 535 return E_OK; 536 } 537 538 /* .............................................................................. */ 539 540 static t_Error GracefulRestart(t_Dtsec *p_Dtsec, e_CommMode mode) 541 { 542 t_DtsecMemMap *p_MemMap; 543 544 ASSERT_COND(p_Dtsec); 545 546 p_MemMap= (t_DtsecMemMap*)(p_Dtsec->p_MemMap); 547 ASSERT_COND(p_MemMap); 548 549 /* clear the graceful receive stop bit */ 550 if(mode & e_COMM_MODE_TX) 551 WRITE_UINT32(p_MemMap->tctrl, 552 GET_UINT32(p_MemMap->tctrl) & ~TCTRL_GTS); 553 554 if(mode & e_COMM_MODE_RX) 555 WRITE_UINT32(p_MemMap->rctrl, 556 GET_UINT32(p_MemMap->rctrl) & ~RCTRL_GRS); 557 558 return E_OK; 559 } 560 561 562 /*****************************************************************************/ 563 /* dTSEC Configs modification functions */ 564 /*****************************************************************************/ 565 566 567 /* .............................................................................. */ 568 569 static t_Error DtsecConfigLoopback(t_Handle h_Dtsec, bool newVal) 570 { 571 572 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; 573 574 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); 575 SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); 576 577 p_Dtsec->p_DtsecDriverParam->loopback = newVal; 578 579 return E_OK; 580 } 581 582 /* .............................................................................. */ 583 584 static t_Error DtsecConfigMaxFrameLength(t_Handle h_Dtsec, uint16_t newVal) 585 { 586 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; 587 588 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); 589 SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); 590 591 p_Dtsec->p_DtsecDriverParam->maxFrameLength = newVal; 592 593 return E_OK; 594 } 595 596 /* .............................................................................. */ 597 598 static t_Error DtsecConfigPadAndCrc(t_Handle h_Dtsec, bool newVal) 599 { 600 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; 601 602 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); 603 SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); 604 605 p_Dtsec->p_DtsecDriverParam->padAndCrcEnable = newVal; 606 607 return E_OK; 608 } 609 610 /* .............................................................................. */ 611 612 static t_Error DtsecConfigHalfDuplex(t_Handle h_Dtsec, bool newVal) 613 { 614 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; 615 616 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); 617 SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); 618 619 p_Dtsec->p_DtsecDriverParam->halfDuplex = newVal; 620 621 return E_OK; 622 } 623 624 /* .............................................................................. */ 625 626 static t_Error DtsecConfigLengthCheck(t_Handle h_Dtsec, bool newVal) 627 { 628 #ifdef FM_LEN_CHECK_ERRATA_FMAN_SW002 629 UNUSED(h_Dtsec); 630 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("LengthCheck!")); 631 632 #else 633 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; 634 635 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); 636 SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); 637 638 p_Dtsec->p_DtsecDriverParam->lengthCheckEnable = newVal; 639 640 return E_OK; 641 #endif /* FM_LEN_CHECK_ERRATA_FMAN_SW002 */ 642 } 643 644 static t_Error DtsecConfigException(t_Handle h_Dtsec, e_FmMacExceptions exception, bool enable) 645 { 646 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; 647 uint32_t bitMask = 0; 648 649 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); 650 SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); 651 652 if(exception != e_FM_MAC_EX_1G_1588_TS_RX_ERR) 653 { 654 GET_EXCEPTION_FLAG(bitMask, exception); 655 if(bitMask) 656 { 657 if (enable) 658 p_Dtsec->exceptions |= bitMask; 659 else 660 p_Dtsec->exceptions &= ~bitMask; 661 } 662 else 663 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception")); 664 } 665 else 666 { 667 if(!p_Dtsec->ptpTsuEnabled) 668 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exception valid for 1588 only")); 669 switch(exception){ 670 case(e_FM_MAC_EX_1G_1588_TS_RX_ERR): 671 if(enable) 672 p_Dtsec->enTsuErrExeption = TRUE; 673 else 674 p_Dtsec->enTsuErrExeption = FALSE; 675 break; 676 default: 677 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception")); 678 } 679 } 680 return E_OK; 681 } 682 /*****************************************************************************/ 683 /* dTSEC Run Time API functions */ 684 /*****************************************************************************/ 685 686 /* .............................................................................. */ 687 688 static t_Error DtsecEnable(t_Handle h_Dtsec, e_CommMode mode) 689 { 690 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; 691 t_DtsecMemMap *p_MemMap ; 692 uint32_t tmpReg32 = 0; 693 694 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); 695 SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_INVALID_HANDLE); 696 697 p_MemMap= (t_DtsecMemMap*)(p_Dtsec->p_MemMap); 698 699 tmpReg32 = GET_UINT32(p_MemMap->maccfg1); 700 if (mode & e_COMM_MODE_RX) 701 tmpReg32 |= MACCFG1_RX_EN; 702 if (mode & e_COMM_MODE_TX) 703 tmpReg32 |= MACCFG1_TX_EN; 704 WRITE_UINT32(p_MemMap->maccfg1, tmpReg32); 705 706 GracefulRestart(p_Dtsec, mode); 707 708 return E_OK; 709 } 710 711 /* .............................................................................. */ 712 713 static t_Error DtsecDisable (t_Handle h_Dtsec, e_CommMode mode) 714 { 715 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; 716 t_DtsecMemMap *p_MemMap ; 717 uint32_t tmpReg32 = 0; 718 719 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); 720 SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_INVALID_HANDLE); 721 722 p_MemMap = (t_DtsecMemMap*)(p_Dtsec->p_MemMap); 723 724 GracefulStop(p_Dtsec, mode); 725 726 tmpReg32 = GET_UINT32(p_MemMap->maccfg1); 727 if (mode & e_COMM_MODE_RX) 728 tmpReg32 &= ~MACCFG1_RX_EN; 729 if (mode & e_COMM_MODE_TX) 730 tmpReg32 &= ~MACCFG1_TX_EN; 731 WRITE_UINT32(p_MemMap->maccfg1, tmpReg32); 732 733 return E_OK; 734 } 735 736 /* .............................................................................. */ 737 738 static t_Error DtsecTxMacPause(t_Handle h_Dtsec, uint16_t pauseTime) 739 { 740 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; 741 uint32_t ptv = 0; 742 t_DtsecMemMap *p_MemMap; 743 744 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_STATE); 745 SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); 746 SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_INVALID_STATE); 747 748 p_MemMap = (t_DtsecMemMap*)(p_Dtsec->p_MemMap); 749 750 if (pauseTime) 751 { 752 #ifdef FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003 753 { 754 if (pauseTime <= 320) 755 RETURN_ERROR(MINOR, E_INVALID_VALUE, 756 ("This pause-time value of %d is illegal due to errata dTSEC-A003!" 757 " value should be greater than 320.")); 758 } 759 #endif /* FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003 */ 760 761 #ifdef FM_SHORT_PAUSE_TIME_ERRATA_DTSEC1 762 { 763 t_FmRevisionInfo revInfo; 764 FM_GetRevision(p_Dtsec->fmMacControllerDriver.h_Fm, &revInfo); 765 if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0)) 766 pauseTime += 2; 767 } 768 #endif /* FM_SHORT_PAUSE_TIME_ERRATA_DTSEC1 */ 769 770 ptv = GET_UINT32(p_MemMap->ptv); 771 ptv |= pauseTime; 772 WRITE_UINT32(p_MemMap->ptv, ptv); 773 774 /* trigger the transmission of a flow-control pause frame */ 775 WRITE_UINT32(p_MemMap->maccfg1, 776 GET_UINT32(p_MemMap->maccfg1) | MACCFG1_TX_FLOW); 777 } 778 else 779 { 780 WRITE_UINT32(p_MemMap->maccfg1, 781 GET_UINT32(p_MemMap->maccfg1) & ~MACCFG1_TX_FLOW); 782 } 783 784 return E_OK; 785 } 786 787 /* .............................................................................. */ 788 789 static t_Error DtsecRxIgnoreMacPause(t_Handle h_Dtsec, bool en) 790 { 791 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; 792 t_DtsecMemMap *p_MemMap; 793 uint32_t tmpReg32; 794 795 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_STATE); 796 SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); 797 SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_INVALID_STATE); 798 799 p_MemMap = (t_DtsecMemMap*)(p_Dtsec->p_MemMap); 800 801 tmpReg32 = GET_UINT32(p_MemMap->maccfg1); 802 if (en) 803 tmpReg32 &= ~MACCFG1_RX_FLOW; 804 else 805 tmpReg32 |= MACCFG1_RX_FLOW; 806 WRITE_UINT32(p_MemMap->maccfg1, tmpReg32); 807 808 return E_OK; 809 } 810 811 812 /* .............................................................................. */ 813 814 static t_Error DtsecEnable1588TimeStamp(t_Handle h_Dtsec) 815 { 816 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; 817 818 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); 819 SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); 820 #ifdef FM_10_100_SGMII_NO_TS_ERRATA_DTSEC3 821 if((p_Dtsec->enetMode == e_ENET_MODE_SGMII_10) || (p_Dtsec->enetMode == e_ENET_MODE_SGMII_100)) 822 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("1588TimeStamp in 10/100 SGMII")); 823 #endif /* FM_10_100_SGMII_NO_TS_ERRATA_DTSEC3 */ 824 p_Dtsec->ptpTsuEnabled = TRUE; 825 WRITE_UINT32(p_Dtsec->p_MemMap->rctrl, GET_UINT32(p_Dtsec->p_MemMap->rctrl) | RCTRL_RTSE); 826 WRITE_UINT32(p_Dtsec->p_MemMap->tctrl, GET_UINT32(p_Dtsec->p_MemMap->tctrl) | TCTRL_TTSE); 827 828 return E_OK; 829 } 830 831 static t_Error DtsecDisable1588TimeStamp(t_Handle h_Dtsec) 832 { 833 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; 834 835 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); 836 SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); 837 838 p_Dtsec->ptpTsuEnabled = FALSE; 839 WRITE_UINT32(p_Dtsec->p_MemMap->rctrl, GET_UINT32(p_Dtsec->p_MemMap->rctrl) & ~RCTRL_RTSE); 840 WRITE_UINT32(p_Dtsec->p_MemMap->tctrl, GET_UINT32(p_Dtsec->p_MemMap->tctrl) & ~TCTRL_TTSE); 841 842 return E_OK; 843 } 844 845 /* .............................................................................. */ 846 847 static t_Error DtsecGetStatistics(t_Handle h_Dtsec, t_FmMacStatistics *p_Statistics) 848 { 849 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; 850 t_DtsecMemMap *p_DtsecMemMap; 851 852 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); 853 SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_NULL_POINTER); 854 SANITY_CHECK_RETURN_ERROR(p_Statistics, E_NULL_POINTER); 855 856 if (p_Dtsec->statisticsLevel == e_FM_MAC_NONE_STATISTICS) 857 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Statistics disabled")); 858 859 p_DtsecMemMap = p_Dtsec->p_MemMap; 860 memset(p_Statistics, 0xff, sizeof(t_FmMacStatistics)); 861 862 if (p_Dtsec->statisticsLevel == e_FM_MAC_FULL_STATISTICS) 863 { 864 p_Statistics->eStatPkts64 = (MASK22BIT & GET_UINT32(p_DtsecMemMap->tr64)) 865 + p_Dtsec->internalStatistics.tr64; /**< r-10G tr-DT 64 byte frame counter */ 866 p_Statistics->eStatPkts65to127 = (MASK22BIT & GET_UINT32(p_DtsecMemMap->tr127)) 867 + p_Dtsec->internalStatistics.tr127; /**< r-10G 65 to 127 byte frame counter */ 868 p_Statistics->eStatPkts128to255 = (MASK22BIT & GET_UINT32(p_DtsecMemMap->tr255)) 869 + p_Dtsec->internalStatistics.tr255; /**< r-10G 128 to 255 byte frame counter */ 870 p_Statistics->eStatPkts256to511 = (MASK22BIT & GET_UINT32(p_DtsecMemMap->tr511)) 871 + p_Dtsec->internalStatistics.tr511; /**< r-10G 256 to 511 byte frame counter */ 872 p_Statistics->eStatPkts512to1023 = (MASK22BIT & GET_UINT32(p_DtsecMemMap->tr1k)) 873 + p_Dtsec->internalStatistics.tr1k; /**< r-10G 512 to 1023 byte frame counter */ 874 p_Statistics->eStatPkts1024to1518 = (MASK22BIT & GET_UINT32(p_DtsecMemMap->trmax)) 875 + p_Dtsec->internalStatistics.trmax; /**< r-10G 1024 to 1518 byte frame counter */ 876 p_Statistics->eStatPkts1519to1522 = (MASK22BIT & GET_UINT32(p_DtsecMemMap->trmgv)) 877 + p_Dtsec->internalStatistics.trmgv; /**< r-10G 1519 to 1522 byte good frame count */ 878 /* MIB II */ 879 p_Statistics->ifInOctets = GET_UINT32(p_DtsecMemMap->rbyt) 880 + p_Dtsec->internalStatistics.rbyt; /**< Total number of byte received. */ 881 p_Statistics->ifInPkts = (MASK22BIT & GET_UINT32(p_DtsecMemMap->rpkt)) 882 + p_Dtsec->internalStatistics.rpkt; /**< Total number of packets received.*/ 883 p_Statistics->ifInMcastPkts = (MASK22BIT & GET_UINT32(p_DtsecMemMap->rmca)) 884 + p_Dtsec->internalStatistics.rmca; /**< Total number of multicast frame received*/ 885 p_Statistics->ifInBcastPkts = (MASK22BIT & GET_UINT32(p_DtsecMemMap->rbca)) 886 + p_Dtsec->internalStatistics.rbca; /**< Total number of broadcast frame received */ 887 p_Statistics->ifOutOctets = GET_UINT32(p_DtsecMemMap->tbyt) 888 + p_Dtsec->internalStatistics.tbyt; /**< Total number of byte sent. */ 889 p_Statistics->ifOutPkts = (MASK22BIT & GET_UINT32(p_DtsecMemMap->tpkt)) 890 + p_Dtsec->internalStatistics.tpkt; /**< Total number of packets sent .*/ 891 p_Statistics->ifOutMcastPkts = (MASK22BIT & GET_UINT32(p_DtsecMemMap->tmca)) 892 + p_Dtsec->internalStatistics.tmca; /**< Total number of multicast frame sent */ 893 p_Statistics->ifOutBcastPkts = (MASK22BIT & GET_UINT32(p_DtsecMemMap->tbca)) 894 + p_Dtsec->internalStatistics.tbca; /**< Total number of multicast frame sent */ 895 } 896 /* */ 897 p_Statistics->eStatFragments = (MASK16BIT & GET_UINT32(p_DtsecMemMap->rfrg)) 898 + p_Dtsec->internalStatistics.rfrg; /**< Total number of packets that were less than 64 octets long with a wrong CRC.*/ 899 p_Statistics->eStatJabbers = (MASK16BIT & GET_UINT32(p_DtsecMemMap->rjbr)) 900 + p_Dtsec->internalStatistics.rjbr; /**< Total number of packets longer than valid maximum length octets */ 901 902 p_Statistics->eStatsDropEvents = (MASK16BIT & GET_UINT32(p_DtsecMemMap->rdrp)) 903 + p_Dtsec->internalStatistics.rdrp; /**< number of dropped packets due to internal errors of the MAC Client. */ 904 p_Statistics->eStatCRCAlignErrors = (MASK16BIT & GET_UINT32(p_DtsecMemMap->raln)) 905 + p_Dtsec->internalStatistics.raln; /**< Incremented when frames of correct length but with CRC error are received.*/ 906 907 p_Statistics->eStatUndersizePkts = (MASK16BIT & GET_UINT32(p_DtsecMemMap->rund)) 908 + p_Dtsec->internalStatistics.rund; /**< Total number of packets that were less than 64 octets long with a good CRC.*/ 909 p_Statistics->eStatOversizePkts = (MASK16BIT & GET_UINT32(p_DtsecMemMap->rovr)) 910 + p_Dtsec->internalStatistics.rovr; /**< T,B.D*/ 911 /* Pause */ 912 p_Statistics->reStatPause = (MASK16BIT & GET_UINT32(p_DtsecMemMap->rxpf)) 913 + p_Dtsec->internalStatistics.rxpf; /**< Pause MAC Control received */ 914 p_Statistics->teStatPause = (MASK16BIT & GET_UINT32(p_DtsecMemMap->txpf)) 915 + p_Dtsec->internalStatistics.txpf; /**< Pause MAC Control sent */ 916 917 p_Statistics->ifInDiscards = p_Statistics->eStatsDropEvents; /**< Frames received, but discarded due to problems within the MAC RX. */ 918 919 p_Statistics->ifInErrors = p_Statistics->eStatsDropEvents 920 + p_Statistics->eStatCRCAlignErrors 921 + (MASK16BIT & GET_UINT32(p_DtsecMemMap->rflr)) 922 + p_Dtsec->internalStatistics.rflr 923 + (MASK16BIT & GET_UINT32(p_DtsecMemMap->rcde)) 924 + p_Dtsec->internalStatistics.rcde 925 + (MASK16BIT & GET_UINT32(p_DtsecMemMap->rcse)) 926 + p_Dtsec->internalStatistics.rcse; 927 928 p_Statistics->ifOutDiscards = (MASK16BIT & GET_UINT32(p_DtsecMemMap->tdrp)) 929 + p_Dtsec->internalStatistics.tdrp; /**< Frames received, but discarded due to problems within the MAC TX N/A!.*/ 930 p_Statistics->ifOutErrors = p_Statistics->ifOutDiscards /**< Number of frames transmitted with error: */ 931 + (MASK12BIT & GET_UINT32(p_DtsecMemMap->tfcs)) 932 + p_Dtsec->internalStatistics.tfcs; 933 934 return E_OK; 935 } 936 937 /* .............................................................................. */ 938 939 static t_Error DtsecModifyMacAddress (t_Handle h_Dtsec, t_EnetAddr *p_EnetAddr) 940 { 941 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; 942 t_DtsecMemMap *p_DtsecMemMap; 943 uint32_t tmpReg32 = 0; 944 uint64_t addr; 945 946 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); 947 SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_NULL_POINTER); 948 949 p_DtsecMemMap = p_Dtsec->p_MemMap; 950 /* Initialize MAC Station Address registers (1 & 2) */ 951 /* Station address have to be swapped (big endian to little endian */ 952 addr = ((*(uint64_t *)p_EnetAddr) >> 16); 953 p_Dtsec->addr = addr; 954 955 tmpReg32 = (uint32_t)(addr); 956 SwapUint32P(&tmpReg32); 957 WRITE_UINT32(p_DtsecMemMap->macstnaddr1, tmpReg32); 958 959 tmpReg32 = (uint32_t)(addr>>32); 960 SwapUint32P(&tmpReg32); 961 WRITE_UINT32(p_DtsecMemMap->macstnaddr2, tmpReg32); 962 963 return E_OK; 964 } 965 966 /* .............................................................................. */ 967 968 static t_Error DtsecResetCounters (t_Handle h_Dtsec) 969 { 970 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; 971 972 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); 973 974 /* clear HW counters */ 975 WRITE_UINT32(p_Dtsec->p_MemMap->ecntrl, GET_UINT32(p_Dtsec->p_MemMap->ecntrl) | ECNTRL_CLRCNT); 976 977 /* clear SW counters holding carries */ 978 memset((char *)&p_Dtsec->internalStatistics, (char)0x0, sizeof(t_InternalStatistics)); 979 980 return E_OK; 981 } 982 983 /* .............................................................................. */ 984 985 static t_Error DtsecAddExactMatchMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr) 986 { 987 t_Dtsec *p_Dtsec = (t_Dtsec *) h_Dtsec; 988 uint64_t ethAddr; 989 uint8_t paddrNum; 990 991 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); 992 993 ethAddr = ((*(uint64_t *)p_EthAddr) >> 16); 994 995 if (ethAddr & GROUP_ADDRESS) 996 /* Multicast address has no effect in PADDR */ 997 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Multicast address")); 998 999 /* Make sure no PADDR contains this address */ 1000 for (paddrNum = 0; paddrNum < DTSEC_NUM_OF_PADDRS; paddrNum++) 1001 if (p_Dtsec->indAddrRegUsed[paddrNum]) 1002 if (p_Dtsec->paddr[paddrNum] == ethAddr) 1003 RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG); 1004 1005 /* Find first unused PADDR */ 1006 for (paddrNum = 0; paddrNum < DTSEC_NUM_OF_PADDRS; paddrNum++) 1007 if (!(p_Dtsec->indAddrRegUsed[paddrNum])) 1008 { 1009 /* mark this PADDR as used */ 1010 p_Dtsec->indAddrRegUsed[paddrNum] = TRUE; 1011 /* store address */ 1012 p_Dtsec->paddr[paddrNum] = ethAddr; 1013 1014 /* put in hardware */ 1015 HardwareAddAddrInPaddr(p_Dtsec, ðAddr, paddrNum); 1016 p_Dtsec->numOfIndAddrInRegs++; 1017 1018 return E_OK; 1019 } 1020 1021 /* No free PADDR */ 1022 RETURN_ERROR(MAJOR, E_FULL, NO_MSG); 1023 } 1024 1025 /* .............................................................................. */ 1026 1027 static t_Error DtsecDelExactMatchMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr) 1028 { 1029 t_Dtsec *p_Dtsec = (t_Dtsec *) h_Dtsec; 1030 uint64_t ethAddr; 1031 uint8_t paddrNum; 1032 1033 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); 1034 1035 ethAddr = ((*(uint64_t *)p_EthAddr) >> 16); 1036 1037 /* Find used PADDR containing this address */ 1038 for (paddrNum = 0; paddrNum < DTSEC_NUM_OF_PADDRS; paddrNum++) 1039 { 1040 if ((p_Dtsec->indAddrRegUsed[paddrNum]) && 1041 (p_Dtsec->paddr[paddrNum] == ethAddr)) 1042 { 1043 /* mark this PADDR as not used */ 1044 p_Dtsec->indAddrRegUsed[paddrNum] = FALSE; 1045 /* clear in hardware */ 1046 HardwareClearAddrInPaddr(p_Dtsec, paddrNum); 1047 p_Dtsec->numOfIndAddrInRegs--; 1048 1049 return E_OK; 1050 } 1051 } 1052 1053 RETURN_ERROR(MAJOR, E_NOT_FOUND, NO_MSG); 1054 } 1055 1056 /* .............................................................................. */ 1057 1058 static t_Error DtsecAddHashMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr) 1059 { 1060 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; 1061 t_DtsecMemMap *p_DtsecMemMap; 1062 uint32_t crc; 1063 uint8_t crcMirror, reg; 1064 uint32_t bitMask; 1065 t_EthHashEntry *p_HashEntry; 1066 uint64_t ethAddr; 1067 1068 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); 1069 SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_NULL_POINTER); 1070 1071 p_DtsecMemMap = p_Dtsec->p_MemMap; 1072 1073 ethAddr = ((*(uint64_t *)p_EthAddr) >> 16); 1074 1075 /* CRC calculation */ 1076 GET_MAC_ADDR_CRC(ethAddr, crc); 1077 1078 /* calculate the "crc mirror" */ 1079 crcMirror = MIRROR((uint8_t)crc); 1080 1081 /* 3 MSB bits define the register */ 1082 reg = (uint8_t)(crcMirror >> 5); 1083 /* 5 LSB bits define the bit within the register */ 1084 bitMask = 0x80000000 >> (crcMirror & 0x1f); 1085 1086 /* Create element to be added to the driver hash table */ 1087 p_HashEntry = (t_EthHashEntry *)XX_Malloc(sizeof(t_EthHashEntry)); 1088 p_HashEntry->addr = ethAddr; 1089 INIT_LIST(&p_HashEntry->node); 1090 1091 if (ethAddr & GROUP_ADDRESS) 1092 { 1093 /* Group Address */ 1094 LIST_AddToTail(&(p_HashEntry->node), &(p_Dtsec->p_MulticastAddrHash->p_Lsts[crcMirror])); 1095 /* Set the appropriate bit in GADDR0-7 */ 1096 WRITE_UINT32(p_DtsecMemMap->gaddr[reg], 1097 GET_UINT32(p_DtsecMemMap->gaddr[reg]) | bitMask); 1098 } 1099 else 1100 { 1101 LIST_AddToTail(&(p_HashEntry->node), &(p_Dtsec->p_UnicastAddrHash->p_Lsts[crcMirror])); 1102 /* Set the appropriate bit in IADDR0-7 */ 1103 WRITE_UINT32(p_DtsecMemMap->igaddr[reg], 1104 GET_UINT32(p_DtsecMemMap->igaddr[reg]) | bitMask); 1105 } 1106 1107 return E_OK; 1108 } 1109 1110 /* .............................................................................. */ 1111 1112 static t_Error DtsecDelHashMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr) 1113 { 1114 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; 1115 t_DtsecMemMap *p_DtsecMemMap; 1116 t_List *p_Pos; 1117 uint32_t crc; 1118 uint8_t crcMirror, reg; 1119 uint32_t bitMask; 1120 t_EthHashEntry *p_HashEntry = NULL; 1121 uint64_t ethAddr; 1122 1123 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); 1124 SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_NULL_POINTER); 1125 1126 p_DtsecMemMap = p_Dtsec->p_MemMap; 1127 1128 ethAddr = ((*(uint64_t *)p_EthAddr) >> 16); 1129 1130 /* CRC calculation */ 1131 GET_MAC_ADDR_CRC(ethAddr, crc); 1132 1133 /* calculate the "crc mirror" */ 1134 crcMirror = MIRROR((uint8_t)crc); 1135 1136 /* 3 MSB bits define the register */ 1137 reg =(uint8_t)( crcMirror >> 5); 1138 /* 5 LSB bits define the bit within the register */ 1139 bitMask = 0x80000000 >> (crcMirror & 0x1f); 1140 1141 if (ethAddr & GROUP_ADDRESS) 1142 { 1143 /* Group Address */ 1144 LIST_FOR_EACH(p_Pos, &(p_Dtsec->p_MulticastAddrHash->p_Lsts[crcMirror])) 1145 { 1146 p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos); 1147 if(p_HashEntry->addr == ethAddr) 1148 { 1149 LIST_DelAndInit(&p_HashEntry->node); 1150 XX_Free(p_HashEntry); 1151 break; 1152 } 1153 } 1154 if(LIST_IsEmpty(&p_Dtsec->p_MulticastAddrHash->p_Lsts[crcMirror])) 1155 WRITE_UINT32(p_DtsecMemMap->gaddr[reg], 1156 GET_UINT32(p_DtsecMemMap->gaddr[reg]) & ~bitMask); 1157 } 1158 else 1159 { 1160 /* Individual Address */ 1161 LIST_FOR_EACH(p_Pos, &(p_Dtsec->p_UnicastAddrHash->p_Lsts[crcMirror])) 1162 { 1163 p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos); 1164 if(p_HashEntry->addr == ethAddr) 1165 { 1166 LIST_DelAndInit(&p_HashEntry->node); 1167 XX_Free(p_HashEntry); 1168 break; 1169 } 1170 } 1171 if(LIST_IsEmpty(&p_Dtsec->p_UnicastAddrHash->p_Lsts[crcMirror])) 1172 WRITE_UINT32(p_DtsecMemMap->igaddr[reg], 1173 GET_UINT32(p_DtsecMemMap->igaddr[reg]) & ~bitMask); 1174 } 1175 1176 /* address does not exist */ 1177 ASSERT_COND(p_HashEntry != NULL); 1178 1179 return E_OK; 1180 } 1181 1182 1183 /* .............................................................................. */ 1184 1185 static t_Error DtsecSetPromiscuous(t_Handle h_Dtsec, bool newVal) 1186 { 1187 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; 1188 t_DtsecMemMap *p_DtsecMemMap; 1189 uint32_t tmpReg32; 1190 1191 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); 1192 SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_HANDLE); 1193 SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_NULL_POINTER); 1194 1195 p_DtsecMemMap = p_Dtsec->p_MemMap; 1196 1197 tmpReg32 = GET_UINT32(p_DtsecMemMap->rctrl); 1198 1199 if (newVal) 1200 tmpReg32 |= RCTRL_PROM; 1201 else 1202 tmpReg32 &= ~RCTRL_PROM; 1203 1204 WRITE_UINT32(p_DtsecMemMap->rctrl, tmpReg32); 1205 1206 return E_OK; 1207 } 1208 1209 /* .............................................................................. */ 1210 1211 static t_Error DtsecSetStatistics(t_Handle h_Dtsec, e_FmMacStatisticsLevel statisticsLevel) 1212 { 1213 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; 1214 t_DtsecMemMap *p_DtsecMemMap; 1215 1216 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); 1217 SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_NULL_POINTER); 1218 1219 p_DtsecMemMap = p_Dtsec->p_MemMap; 1220 1221 p_Dtsec->statisticsLevel = statisticsLevel; 1222 1223 switch (p_Dtsec->statisticsLevel) 1224 { 1225 case(e_FM_MAC_NONE_STATISTICS): 1226 WRITE_UINT32(p_DtsecMemMap->cam1,0xffffffff); 1227 WRITE_UINT32(p_DtsecMemMap->cam2,0xffffffff); 1228 WRITE_UINT32(p_DtsecMemMap->ecntrl, GET_UINT32(p_DtsecMemMap->ecntrl) & ~ECNTRL_STEN); 1229 WRITE_UINT32(p_DtsecMemMap->imask, GET_UINT32(p_DtsecMemMap->imask) & ~IMASK_MSROEN); 1230 p_Dtsec->exceptions &= ~IMASK_MSROEN; 1231 break; 1232 case(e_FM_MAC_PARTIAL_STATISTICS): 1233 WRITE_UINT32(p_DtsecMemMap->cam1, CAM1_ERRORS_ONLY); 1234 WRITE_UINT32(p_DtsecMemMap->cam2, CAM2_ERRORS_ONLY); 1235 WRITE_UINT32(p_DtsecMemMap->ecntrl, GET_UINT32(p_DtsecMemMap->ecntrl) | ECNTRL_STEN); 1236 WRITE_UINT32(p_DtsecMemMap->imask, GET_UINT32(p_DtsecMemMap->imask) | IMASK_MSROEN); 1237 p_Dtsec->exceptions |= IMASK_MSROEN; 1238 break; 1239 case(e_FM_MAC_FULL_STATISTICS): 1240 WRITE_UINT32(p_DtsecMemMap->cam1,0); 1241 WRITE_UINT32(p_DtsecMemMap->cam2,0); 1242 WRITE_UINT32(p_DtsecMemMap->ecntrl, GET_UINT32(p_DtsecMemMap->ecntrl) | ECNTRL_STEN); 1243 WRITE_UINT32(p_DtsecMemMap->imask, GET_UINT32(p_DtsecMemMap->imask) | IMASK_MSROEN); 1244 p_Dtsec->exceptions |= IMASK_MSROEN; 1245 break; 1246 default: 1247 RETURN_ERROR(MINOR, E_INVALID_SELECTION, NO_MSG); 1248 } 1249 1250 return E_OK; 1251 } 1252 1253 /* .............................................................................. */ 1254 1255 static t_Error DtsecAdjustLink(t_Handle h_Dtsec, e_EnetSpeed speed, bool fullDuplex) 1256 { 1257 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; 1258 t_DtsecMemMap *p_DtsecMemMap; 1259 uint32_t tmpReg32; 1260 1261 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); 1262 SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_HANDLE); 1263 p_DtsecMemMap = p_Dtsec->p_MemMap; 1264 SANITY_CHECK_RETURN_ERROR(p_DtsecMemMap, E_INVALID_HANDLE); 1265 1266 if ((!fullDuplex) && (speed >= e_ENET_SPEED_1000)) 1267 RETURN_ERROR(MAJOR, E_CONFLICT, ("Ethernet interface does not support Half Duplex mode")); 1268 1269 p_Dtsec->enetMode = MAKE_ENET_MODE(ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode), speed); 1270 p_Dtsec->halfDuplex = !fullDuplex; 1271 1272 tmpReg32 = GET_UINT32(p_DtsecMemMap->maccfg2); 1273 if(p_Dtsec->halfDuplex) 1274 tmpReg32 &= ~MACCFG2_FULL_DUPLEX; 1275 else 1276 tmpReg32 |= MACCFG2_FULL_DUPLEX; 1277 1278 tmpReg32 &= ~(MACCFG2_NIBBLE_MODE | MACCFG2_BYTE_MODE); 1279 if((p_Dtsec->enetMode == e_ENET_MODE_RGMII_10) || 1280 (p_Dtsec->enetMode == e_ENET_MODE_RGMII_100)|| 1281 (p_Dtsec->enetMode == e_ENET_MODE_SGMII_10) || 1282 (p_Dtsec->enetMode == e_ENET_MODE_SGMII_100)) 1283 tmpReg32 |= MACCFG2_NIBBLE_MODE; 1284 else if((p_Dtsec->enetMode == e_ENET_MODE_RGMII_1000) || 1285 (p_Dtsec->enetMode == e_ENET_MODE_SGMII_1000)|| 1286 (p_Dtsec->enetMode == e_ENET_MODE_GMII_1000)) 1287 tmpReg32 |= MACCFG2_BYTE_MODE; 1288 WRITE_UINT32(p_DtsecMemMap->maccfg2, tmpReg32); 1289 1290 tmpReg32 = GET_UINT32(p_DtsecMemMap->ecntrl); 1291 if (!(tmpReg32 & ECNTRL_CFG_RO)) 1292 { 1293 if ((p_Dtsec->enetMode == e_ENET_MODE_RGMII_100) || 1294 (p_Dtsec->enetMode == e_ENET_MODE_SGMII_100)) 1295 tmpReg32 |= ECNTRL_R100M; 1296 else 1297 tmpReg32 &= ~ECNTRL_R100M; 1298 WRITE_UINT32(p_DtsecMemMap->ecntrl, tmpReg32); 1299 } 1300 1301 return E_OK; 1302 } 1303 1304 /* .............................................................................. */ 1305 1306 static t_Error DtsecGetId(t_Handle h_Dtsec, uint32_t *macId) 1307 { 1308 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; 1309 1310 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); 1311 SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_HANDLE); 1312 1313 *macId = p_Dtsec->macId; 1314 1315 return E_OK; 1316 } 1317 1318 /* .............................................................................. */ 1319 1320 static t_Error DtsecGetVersion(t_Handle h_Dtsec, uint32_t *macVersion) 1321 { 1322 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; 1323 t_DtsecMemMap *p_DtsecMemMap; 1324 1325 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); 1326 SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_HANDLE); 1327 SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_NULL_POINTER); 1328 1329 p_DtsecMemMap = p_Dtsec->p_MemMap; 1330 *macVersion = GET_UINT32(p_DtsecMemMap->tsec_id1); 1331 1332 return E_OK; 1333 } 1334 1335 /* .............................................................................. */ 1336 1337 static t_Error DtsecSetException(t_Handle h_Dtsec, e_FmMacExceptions exception, bool enable) 1338 { 1339 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; 1340 uint32_t tmpReg, bitMask = 0; 1341 t_DtsecMemMap *p_DtsecMemMap; 1342 1343 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); 1344 SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_HANDLE); 1345 SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_NULL_POINTER); 1346 1347 p_DtsecMemMap = p_Dtsec->p_MemMap; 1348 1349 if(exception != e_FM_MAC_EX_1G_1588_TS_RX_ERR) 1350 { 1351 GET_EXCEPTION_FLAG(bitMask, exception); 1352 if(bitMask) 1353 { 1354 if (enable) 1355 p_Dtsec->exceptions |= bitMask; 1356 else 1357 p_Dtsec->exceptions &= ~bitMask; 1358 } 1359 else 1360 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception")); 1361 1362 tmpReg = GET_UINT32(p_DtsecMemMap->imask); 1363 if(enable) 1364 tmpReg |= bitMask; 1365 else 1366 tmpReg &= ~bitMask; 1367 WRITE_UINT32(p_DtsecMemMap->imask, tmpReg); 1368 1369 /* warn if MIB OVFL is disabled and statistic gathering is enabled */ 1370 if((exception == e_FM_MAC_EX_1G_RX_MIB_CNT_OVFL) && 1371 !enable && 1372 (p_Dtsec->statisticsLevel != e_FM_MAC_NONE_STATISTICS)) 1373 DBG(WARNING, ("Disabled MIB counters overflow exceptions. Counters value may be inaccurate due to unregistered overflow")); 1374 1375 } 1376 else 1377 { 1378 if(!p_Dtsec->ptpTsuEnabled) 1379 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exception valid for 1588 only")); 1380 tmpReg = GET_UINT32(p_DtsecMemMap->tmr_pemask); 1381 switch(exception){ 1382 case(e_FM_MAC_EX_1G_1588_TS_RX_ERR): 1383 if(enable) 1384 { 1385 p_Dtsec->enTsuErrExeption = TRUE; 1386 WRITE_UINT32(p_DtsecMemMap->tmr_pemask, tmpReg | PEMASK_TSRE); 1387 } 1388 else 1389 { 1390 p_Dtsec->enTsuErrExeption = FALSE; 1391 WRITE_UINT32(p_DtsecMemMap->tmr_pemask, tmpReg & ~PEMASK_TSRE); 1392 } 1393 break; 1394 default: 1395 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception")); 1396 } 1397 } 1398 1399 return E_OK; 1400 } 1401 1402 /* ........................................................................... */ 1403 1404 #if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) 1405 static t_Error DtsecDumpRegs(t_Handle h_Dtsec) 1406 { 1407 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; 1408 int i = 0; 1409 1410 DECLARE_DUMP; 1411 1412 if (p_Dtsec->p_MemMap) 1413 { 1414 1415 DUMP_TITLE(p_Dtsec->p_MemMap, ("MAC %d: ", p_Dtsec->macId)); 1416 DUMP_VAR(p_Dtsec->p_MemMap, tsec_id1); 1417 DUMP_VAR(p_Dtsec->p_MemMap, tsec_id2); 1418 DUMP_VAR(p_Dtsec->p_MemMap, ievent); 1419 DUMP_VAR(p_Dtsec->p_MemMap, imask); 1420 DUMP_VAR(p_Dtsec->p_MemMap, edis); 1421 DUMP_VAR(p_Dtsec->p_MemMap, ecntrl); 1422 DUMP_VAR(p_Dtsec->p_MemMap, ptv); 1423 DUMP_VAR(p_Dtsec->p_MemMap, tmr_ctrl); 1424 DUMP_VAR(p_Dtsec->p_MemMap, tmr_pevent); 1425 DUMP_VAR(p_Dtsec->p_MemMap, tmr_pemask); 1426 DUMP_VAR(p_Dtsec->p_MemMap, tctrl); 1427 DUMP_VAR(p_Dtsec->p_MemMap, rctrl); 1428 DUMP_VAR(p_Dtsec->p_MemMap, maccfg1); 1429 DUMP_VAR(p_Dtsec->p_MemMap, maccfg2); 1430 DUMP_VAR(p_Dtsec->p_MemMap, ipgifg); 1431 DUMP_VAR(p_Dtsec->p_MemMap, hafdup); 1432 DUMP_VAR(p_Dtsec->p_MemMap, maxfrm); 1433 1434 DUMP_VAR(p_Dtsec->p_MemMap, macstnaddr1); 1435 DUMP_VAR(p_Dtsec->p_MemMap, macstnaddr2); 1436 1437 DUMP_SUBSTRUCT_ARRAY(i, 8) 1438 { 1439 DUMP_VAR(p_Dtsec->p_MemMap, macaddr[i].exact_match1); 1440 DUMP_VAR(p_Dtsec->p_MemMap, macaddr[i].exact_match2); 1441 } 1442 } 1443 1444 return E_OK; 1445 } 1446 #endif /* (defined(DEBUG_ERRORS) && ... */ 1447 1448 1449 /*****************************************************************************/ 1450 /* FM Init & Free API */ 1451 /*****************************************************************************/ 1452 1453 /* .............................................................................. */ 1454 1455 static t_Error DtsecInit(t_Handle h_Dtsec) 1456 { 1457 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; 1458 t_DtsecDriverParam *p_DtsecDriverParam; 1459 t_DtsecMemMap *p_DtsecMemMap; 1460 int i; 1461 uint32_t tmpReg32; 1462 uint64_t addr; 1463 t_Error err; 1464 1465 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); 1466 SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); 1467 SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_INVALID_STATE); 1468 1469 CHECK_INIT_PARAMETERS(p_Dtsec, CheckInitParameters); 1470 1471 p_DtsecDriverParam = p_Dtsec->p_DtsecDriverParam; 1472 p_Dtsec->halfDuplex = p_DtsecDriverParam->halfDuplex; 1473 p_Dtsec->debugMode = p_DtsecDriverParam->debugMode; 1474 p_DtsecMemMap = p_Dtsec->p_MemMap; 1475 1476 /*************dtsec_id2******************/ 1477 tmpReg32 = GET_UINT32(p_DtsecMemMap->tsec_id2); 1478 1479 if ((p_Dtsec->enetMode == e_ENET_MODE_RGMII_10) || 1480 (p_Dtsec->enetMode == e_ENET_MODE_RGMII_100) || 1481 (p_Dtsec->enetMode == e_ENET_MODE_RGMII_1000) || 1482 (p_Dtsec->enetMode == e_ENET_MODE_RMII_10) || 1483 (p_Dtsec->enetMode == e_ENET_MODE_RMII_100)) 1484 if(tmpReg32 & ID2_INT_REDUCED_OFF) 1485 { 1486 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("no support for reduced interface in current DTSEC version")); 1487 } 1488 1489 if ((p_Dtsec->enetMode == e_ENET_MODE_SGMII_10) || 1490 (p_Dtsec->enetMode == e_ENET_MODE_SGMII_100) || 1491 (p_Dtsec->enetMode == e_ENET_MODE_SGMII_1000)|| 1492 (p_Dtsec->enetMode == e_ENET_MODE_MII_10) || 1493 (p_Dtsec->enetMode == e_ENET_MODE_MII_100)) 1494 if(tmpReg32 & ID2_INT_NORMAL_OFF) 1495 { 1496 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("no support for normal interface in current DTSEC version")); 1497 } 1498 /*************dtsec_id2******************/ 1499 1500 /***************EDIS************************/ 1501 WRITE_UINT32(p_DtsecMemMap->edis, p_DtsecDriverParam->errorDisabled); 1502 /***************EDIS************************/ 1503 1504 /***************ECNTRL************************/ 1505 tmpReg32 = 0; 1506 if ((p_Dtsec->enetMode == e_ENET_MODE_RGMII_10) || 1507 (p_Dtsec->enetMode == e_ENET_MODE_RGMII_100) || 1508 (p_Dtsec->enetMode == e_ENET_MODE_RGMII_1000) || 1509 (p_Dtsec->enetMode == e_ENET_MODE_GMII_1000)) 1510 tmpReg32 |= ECNTRL_GMIIM; 1511 if ((p_Dtsec->enetMode == e_ENET_MODE_SGMII_10) || 1512 (p_Dtsec->enetMode == e_ENET_MODE_SGMII_100) || 1513 (p_Dtsec->enetMode == e_ENET_MODE_SGMII_1000)) 1514 tmpReg32 |= (ECNTRL_SGMIIM | ECNTRL_TBIM); 1515 if (p_Dtsec->enetMode == e_ENET_MODE_QSGMII_1000) 1516 tmpReg32 |= (ECNTRL_SGMIIM | ECNTRL_TBIM | ECNTRL_QSGMIIM); 1517 if ((p_Dtsec->enetMode == e_ENET_MODE_RGMII_1000) || 1518 (p_Dtsec->enetMode == e_ENET_MODE_RGMII_10)|| 1519 (p_Dtsec->enetMode == e_ENET_MODE_RGMII_100)) 1520 tmpReg32 |= ECNTRL_RPM; 1521 if ((p_Dtsec->enetMode == e_ENET_MODE_RGMII_100) || 1522 (p_Dtsec->enetMode == e_ENET_MODE_SGMII_100) || 1523 (p_Dtsec->enetMode == e_ENET_MODE_RMII_100)) 1524 tmpReg32 |= ECNTRL_R100M; 1525 if ((p_Dtsec->enetMode == e_ENET_MODE_RMII_10) || (p_Dtsec->enetMode == e_ENET_MODE_RMII_100)) 1526 tmpReg32 |= ECNTRL_RMM; 1527 WRITE_UINT32(p_DtsecMemMap->ecntrl, tmpReg32); 1528 /***************ECNTRL************************/ 1529 1530 /***************PTV************************/ 1531 tmpReg32 = 0; 1532 #ifdef FM_SHORT_PAUSE_TIME_ERRATA_DTSEC1 1533 { 1534 t_FmRevisionInfo revInfo; 1535 FM_GetRevision(p_Dtsec->fmMacControllerDriver.h_Fm, &revInfo); 1536 if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0)) 1537 p_DtsecDriverParam->pauseTime += 2; 1538 } 1539 #endif /* FM_SHORT_PAUSE_TIME_ERRATA_DTSEC1 */ 1540 if (p_DtsecDriverParam->pauseTime) 1541 tmpReg32 |= (uint32_t)p_DtsecDriverParam->pauseTime; 1542 1543 if (p_DtsecDriverParam->pauseExtended) 1544 tmpReg32 |= ((uint32_t)p_DtsecDriverParam->pauseExtended) << PTV_PTE_OFST; 1545 WRITE_UINT32(p_DtsecMemMap->ptv, tmpReg32); 1546 /***************PTV************************/ 1547 1548 /***************TCTRL************************/ 1549 tmpReg32 = 0; 1550 if(p_DtsecDriverParam->halfDuplex) 1551 { 1552 if(p_DtsecDriverParam->halfDulexFlowControlEn) 1553 tmpReg32 |= TCTRL_THDF; 1554 } 1555 else 1556 { 1557 if(p_DtsecDriverParam->txTimeStampEn) 1558 tmpReg32 |= TCTRL_TTSE; 1559 } 1560 WRITE_UINT32(p_DtsecMemMap->tctrl, tmpReg32); 1561 /***************TCTRL************************/ 1562 1563 /***************RCTRL************************/ 1564 tmpReg32 = 0; 1565 if (p_DtsecDriverParam->packetAlignmentPadding) 1566 tmpReg32 |= ((uint32_t)(0x0000001f & p_DtsecDriverParam->packetAlignmentPadding)) << 16; 1567 if (p_DtsecDriverParam->controlFrameAccept) 1568 tmpReg32 |= RCTRL_CFA; 1569 if (p_DtsecDriverParam->groupHashExtend) 1570 tmpReg32 |= RCTRL_GHTX; 1571 if(p_DtsecDriverParam->rxTimeStampEn) 1572 tmpReg32 |= RCTRL_RTSE; 1573 if (p_DtsecDriverParam->broadcReject) 1574 tmpReg32 |= RCTRL_BC_REJ; 1575 if (p_DtsecDriverParam->rxShortFrame) 1576 tmpReg32 |= RCTRL_RSF; 1577 if (p_DtsecDriverParam->promiscuousEnable) 1578 tmpReg32 |= RCTRL_PROM; 1579 if (p_DtsecDriverParam->exactMatch) 1580 tmpReg32 |= RCTRL_EMEN; 1581 1582 WRITE_UINT32(p_DtsecMemMap->rctrl, tmpReg32); 1583 /***************RCTRL************************/ 1584 1585 /* Assign a Phy Address to the TBI (TBIPA). */ 1586 /* Done also in case that TBI is not selected to avoid */ 1587 /* conflict with the external PHY�s Physical address */ 1588 WRITE_UINT32(p_DtsecMemMap->tbipa, p_DtsecDriverParam->tbiPhyAddr); 1589 1590 /* Reset the management interface */ 1591 WRITE_UINT32(p_Dtsec->p_MiiMemMap->miimcfg, MIIMCFG_RESET_MGMT); 1592 WRITE_UINT32(p_Dtsec->p_MiiMemMap->miimcfg, ~MIIMCFG_RESET_MGMT); 1593 /* Setup the MII Mgmt clock speed */ 1594 WRITE_UINT32(p_Dtsec->p_MiiMemMap->miimcfg, 1595 (uint32_t)GetMiiDiv((int32_t)(((p_Dtsec->fmMacControllerDriver.clkFreq*10)/2)/8))); 1596 1597 if(p_Dtsec->enetMode == e_ENET_MODE_SGMII_1000) 1598 { 1599 uint16_t tmpReg16; 1600 1601 /* Configure the TBI PHY Control Register */ 1602 tmpReg16 = PHY_TBICON_SPEED2 | PHY_TBICON_SRESET; 1603 1604 DTSEC_MII_WritePhyReg(p_Dtsec, p_DtsecDriverParam->tbiPhyAddr, 17, tmpReg16); 1605 1606 tmpReg16 = PHY_TBICON_SPEED2; 1607 1608 DTSEC_MII_WritePhyReg(p_Dtsec, p_DtsecDriverParam->tbiPhyAddr, 17, tmpReg16); 1609 1610 if(!p_DtsecDriverParam->halfDuplex) 1611 tmpReg16 |= PHY_CR_FULLDUPLEX | 0x8000 | PHY_CR_ANE; 1612 1613 DTSEC_MII_WritePhyReg(p_Dtsec, p_DtsecDriverParam->tbiPhyAddr, 0, tmpReg16); 1614 1615 tmpReg16 = 0x01a0; 1616 DTSEC_MII_WritePhyReg(p_Dtsec, p_DtsecDriverParam->tbiPhyAddr, 4, tmpReg16); 1617 1618 tmpReg16 = 0x1340; 1619 DTSEC_MII_WritePhyReg(p_Dtsec, p_DtsecDriverParam->tbiPhyAddr, 0, tmpReg16); 1620 } 1621 1622 /***************TMR_CTL************************/ 1623 WRITE_UINT32(p_DtsecMemMap->tmr_ctrl, 0); 1624 1625 if(p_Dtsec->ptpTsuEnabled) 1626 { 1627 tmpReg32 = 0; 1628 if (p_Dtsec->enTsuErrExeption) 1629 tmpReg32 |= PEMASK_TSRE; 1630 WRITE_UINT32(p_DtsecMemMap->tmr_pemask, tmpReg32); 1631 WRITE_UINT32(p_DtsecMemMap->tmr_pevent, tmpReg32); 1632 } 1633 1634 /***************DEBUG************************/ 1635 tmpReg32 = 0; 1636 if(p_DtsecDriverParam->debugMode) 1637 WRITE_UINT32(p_DtsecMemMap->tsec_id1, TSEC_ID1_DEBUG); 1638 /***************DEBUG************************/ 1639 1640 /***************MACCFG1***********************/ 1641 WRITE_UINT32(p_DtsecMemMap->maccfg1, MACCFG1_SOFT_RESET); 1642 WRITE_UINT32(p_DtsecMemMap->maccfg1, 0); 1643 tmpReg32 = 0; 1644 if(p_DtsecDriverParam->loopback) 1645 tmpReg32 |= MACCFG1_LOOPBACK; 1646 if(p_DtsecDriverParam->actOnRxPauseFrame) 1647 tmpReg32 |= MACCFG1_RX_FLOW; 1648 if(p_DtsecDriverParam->actOnTxPauseFrame) 1649 tmpReg32 |= MACCFG1_TX_FLOW; 1650 WRITE_UINT32(p_DtsecMemMap->maccfg1, tmpReg32); 1651 /***************MACCFG1***********************/ 1652 1653 /***************MACCFG2***********************/ 1654 tmpReg32 = 0; 1655 if( (p_Dtsec->enetMode == e_ENET_MODE_RMII_10) || 1656 (p_Dtsec->enetMode == e_ENET_MODE_RMII_100) || 1657 (p_Dtsec->enetMode == e_ENET_MODE_MII_10) || 1658 (p_Dtsec->enetMode == e_ENET_MODE_MII_100) || 1659 (p_Dtsec->enetMode == e_ENET_MODE_RGMII_10) || 1660 (p_Dtsec->enetMode == e_ENET_MODE_RGMII_100)|| 1661 (p_Dtsec->enetMode == e_ENET_MODE_SGMII_10) || 1662 (p_Dtsec->enetMode == e_ENET_MODE_SGMII_100)) 1663 tmpReg32 |= MACCFG2_NIBBLE_MODE; 1664 else if((p_Dtsec->enetMode == e_ENET_MODE_RGMII_1000) || 1665 (p_Dtsec->enetMode == e_ENET_MODE_SGMII_1000)|| 1666 (p_Dtsec->enetMode == e_ENET_MODE_GMII_1000)|| 1667 (p_Dtsec->enetMode == e_ENET_MODE_QSGMII_1000)) 1668 tmpReg32 |= MACCFG2_BYTE_MODE; 1669 1670 tmpReg32 |= (((uint32_t)p_DtsecDriverParam->preambleLength) & 0x0000000f)<< PREAMBLE_LENGTH_SHIFT; 1671 1672 if(p_DtsecDriverParam->preambleRxEn) 1673 tmpReg32 |= MACCFG2_PRE_AM_Rx_EN; 1674 if(p_DtsecDriverParam->preambleTxEn) 1675 tmpReg32 |= MACCFG2_PRE_AM_Tx_EN; 1676 if(p_DtsecDriverParam->lengthCheckEnable) 1677 tmpReg32 |= MACCFG2_LENGTH_CHECK; 1678 if(p_DtsecDriverParam->padAndCrcEnable) 1679 tmpReg32 |= MACCFG2_PAD_CRC_EN; 1680 if(p_DtsecDriverParam->crcEnable) 1681 tmpReg32 |= MACCFG2_CRC_EN; 1682 if(!p_DtsecDriverParam->halfDuplex) 1683 tmpReg32 |= MACCFG2_FULL_DUPLEX; 1684 WRITE_UINT32(p_DtsecMemMap->maccfg2, tmpReg32); 1685 /***************MACCFG2***********************/ 1686 1687 /***************IPGIFG************************/ 1688 tmpReg32 = 0; 1689 ASSERT_COND(p_DtsecDriverParam->nonBackToBackIpg1 <= p_DtsecDriverParam->nonBackToBackIpg2); 1690 tmpReg32 = (uint32_t)((((uint32_t)p_DtsecDriverParam->nonBackToBackIpg1 << 1691 IPGIFG_NON_BACK_TO_BACK_IPG_1_SHIFT) & IPGIFG_NON_BACK_TO_BACK_IPG_1) | 1692 (((uint32_t)p_DtsecDriverParam->nonBackToBackIpg2 << 1693 IPGIFG_NON_BACK_TO_BACK_IPG_2_SHIFT) & IPGIFG_NON_BACK_TO_BACK_IPG_2) | 1694 (((uint32_t)p_DtsecDriverParam->minIfgEnforcement << 1695 IPGIFG_MIN_IFG_ENFORCEMENT_SHIFT) & IPGIFG_MIN_IFG_ENFORCEMENT) | 1696 ((uint32_t)p_DtsecDriverParam->backToBackIpg & IPGIFG_BACK_TO_BACK_IPG)); 1697 WRITE_UINT32(p_DtsecMemMap->ipgifg, tmpReg32); 1698 /***************IPGIFG************************/ 1699 1700 /***************HAFDUP************************/ 1701 tmpReg32 = 0; 1702 if(p_DtsecDriverParam->alternateBackoffEnable) 1703 { 1704 tmpReg32 = (uint32_t) (HAFDUP_ALT_BEB | (((uint32_t)p_DtsecDriverParam->alternateBackoffVal & 0x0000000f) << 1705 HAFDUP_ALTERNATE_BEB_TRUNCATION_SHIFT)); 1706 } 1707 1708 if(p_DtsecDriverParam->backPressureNoBackoff) 1709 tmpReg32 |= HAFDUP_BP_NO_BACKOFF; 1710 if(p_DtsecDriverParam->noBackoff) 1711 tmpReg32 |= HAFDUP_NO_BACKOFF; 1712 if(p_DtsecDriverParam->excessDefer) 1713 tmpReg32 |= HAFDUP_EXCESS_DEFER; 1714 tmpReg32 |= (((uint32_t)p_DtsecDriverParam->maxRetransmission << 1715 HAFDUP_RETRANSMISSION_MAX_SHIFT )& HAFDUP_RETRANSMISSION_MAX); 1716 tmpReg32|= ((uint32_t)p_DtsecDriverParam->collisionWindow & HAFDUP_COLLISION_WINDOW); 1717 1718 WRITE_UINT32(p_DtsecMemMap->hafdup, tmpReg32); 1719 /***************HAFDUP************************/ 1720 1721 /***************MAXFRM************************/ 1722 /* Initialize MAXFRM */ 1723 WRITE_UINT32(p_DtsecMemMap->maxfrm, 1724 p_DtsecDriverParam->maxFrameLength); 1725 err = FmSetMacMaxFrame(p_Dtsec->fmMacControllerDriver.h_Fm, 1726 e_FM_MAC_1G, 1727 p_Dtsec->fmMacControllerDriver.macId, 1728 p_DtsecDriverParam->maxFrameLength); 1729 if (err) 1730 RETURN_ERROR(MAJOR, err, NO_MSG); 1731 /***************MAXFRM************************/ 1732 1733 /***************CAM1************************/ 1734 WRITE_UINT32(p_DtsecMemMap->cam1,0xffffffff); 1735 WRITE_UINT32(p_DtsecMemMap->cam2,0xffffffff); 1736 1737 /***************IMASK************************/ 1738 WRITE_UINT32(p_DtsecMemMap->imask, p_Dtsec->exceptions); 1739 /***************IMASK************************/ 1740 1741 /***************IEVENT************************/ 1742 WRITE_UINT32(p_DtsecMemMap->ievent, EVENTS_MASK); 1743 1744 /***************MACSTNADDR1/2*****************/ 1745 /* Initialize MAC Station Address registers (1 & 2) */ 1746 /* Station address have to be swapped (big endian to little endian */ 1747 addr = p_Dtsec->addr; 1748 1749 tmpReg32 = (uint32_t)(addr); 1750 SwapUint32P(&tmpReg32); 1751 WRITE_UINT32(p_DtsecMemMap->macstnaddr1, tmpReg32); 1752 1753 tmpReg32 = (uint32_t)(addr>>32); 1754 SwapUint32P(&tmpReg32); 1755 WRITE_UINT32(p_DtsecMemMap->macstnaddr2, tmpReg32); 1756 /***************MACSTNADDR1/2*****************/ 1757 1758 /***************DEBUG*****************/ 1759 WRITE_UINT32(p_DtsecMemMap->tx_threshold, (uint32_t)(p_DtsecDriverParam->fifoTxThr & 0x7f)); 1760 WRITE_UINT32(p_DtsecMemMap->tx_watermark_high, (uint32_t)(p_DtsecDriverParam->fifoTxWatermarkH & 0x7f)); 1761 WRITE_UINT32(p_DtsecMemMap->rx_watermark_low, (uint32_t)(p_DtsecDriverParam->fifoRxWatermarkL & 0x7f)); 1762 /***************DEBUG*****************/ 1763 1764 /*****************HASH************************/ 1765 for(i=0 ; i<NUM_OF_HASH_REGS ; i++) 1766 { 1767 /* Initialize IADDRx */ 1768 WRITE_UINT32(p_DtsecMemMap->igaddr[i], 0); 1769 /* Initialize GADDRx */ 1770 WRITE_UINT32(p_DtsecMemMap->gaddr[i], 0); 1771 } 1772 1773 p_Dtsec->p_MulticastAddrHash = AllocHashTable(HASH_TABLE_SIZE); 1774 if(!p_Dtsec->p_MulticastAddrHash) 1775 { 1776 FreeInitResources(p_Dtsec); 1777 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MC hash table is FAILED")); 1778 } 1779 1780 p_Dtsec->p_UnicastAddrHash = AllocHashTable(HASH_TABLE_SIZE); 1781 if(!p_Dtsec->p_UnicastAddrHash) 1782 { 1783 FreeInitResources(p_Dtsec); 1784 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("UC hash table is FAILED")); 1785 } 1786 1787 /* register err intr handler for dtsec to FPM (err)*/ 1788 FmRegisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Dtsec->macId, e_FM_INTR_TYPE_ERR, DtsecErrException , p_Dtsec); 1789 /* register 1588 intr handler for TMR to FPM (normal)*/ 1790 FmRegisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC_TMR, p_Dtsec->macId, e_FM_INTR_TYPE_NORMAL, Dtsec1588Exception , p_Dtsec); 1791 /* register normal intr handler for dtsec to main interrupt controller. */ 1792 if (p_Dtsec->mdioIrq != NO_IRQ) 1793 { 1794 XX_SetIntr(p_Dtsec->mdioIrq, DtsecException, p_Dtsec); 1795 XX_EnableIntr(p_Dtsec->mdioIrq); 1796 } 1797 1798 XX_Free(p_DtsecDriverParam); 1799 p_Dtsec->p_DtsecDriverParam = NULL; 1800 1801 err = DtsecSetStatistics(p_Dtsec, e_FM_MAC_FULL_STATISTICS); 1802 if(err) 1803 { 1804 FreeInitResources(p_Dtsec); 1805 RETURN_ERROR(MAJOR, err, NO_MSG); 1806 } 1807 1808 return E_OK; 1809 } 1810 1811 /* ........................................................................... */ 1812 1813 static t_Error DtsecFree(t_Handle h_Dtsec) 1814 { 1815 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; 1816 1817 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); 1818 1819 FreeInitResources(p_Dtsec); 1820 1821 if (p_Dtsec->p_DtsecDriverParam) 1822 { 1823 XX_Free(p_Dtsec->p_DtsecDriverParam); 1824 p_Dtsec->p_DtsecDriverParam = NULL; 1825 } 1826 XX_Free (h_Dtsec); 1827 1828 return E_OK; 1829 } 1830 1831 /* .............................................................................. */ 1832 1833 static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacControllerDriver) 1834 { 1835 p_FmMacControllerDriver->f_FM_MAC_Init = DtsecInit; 1836 p_FmMacControllerDriver->f_FM_MAC_Free = DtsecFree; 1837 1838 p_FmMacControllerDriver->f_FM_MAC_SetStatistics = DtsecSetStatistics; 1839 p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback = DtsecConfigLoopback; 1840 p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength = DtsecConfigMaxFrameLength; 1841 1842 p_FmMacControllerDriver->f_FM_MAC_ConfigWan = NULL; /* Not supported on dTSEC */ 1843 1844 p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc = DtsecConfigPadAndCrc; 1845 p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex = DtsecConfigHalfDuplex; 1846 p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck = DtsecConfigLengthCheck; 1847 p_FmMacControllerDriver->f_FM_MAC_ConfigException = DtsecConfigException; 1848 1849 p_FmMacControllerDriver->f_FM_MAC_Enable = DtsecEnable; 1850 p_FmMacControllerDriver->f_FM_MAC_Disable = DtsecDisable; 1851 1852 p_FmMacControllerDriver->f_FM_MAC_SetException = DtsecSetException; 1853 1854 p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous = DtsecSetPromiscuous; 1855 p_FmMacControllerDriver->f_FM_MAC_AdjustLink = DtsecAdjustLink; 1856 1857 p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp = DtsecEnable1588TimeStamp; 1858 p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp = DtsecDisable1588TimeStamp; 1859 1860 p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames = DtsecTxMacPause; 1861 p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames = DtsecRxIgnoreMacPause; 1862 1863 p_FmMacControllerDriver->f_FM_MAC_ResetCounters = DtsecResetCounters; 1864 p_FmMacControllerDriver->f_FM_MAC_GetStatistics = DtsecGetStatistics; 1865 1866 p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr = DtsecModifyMacAddress; 1867 p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr = DtsecAddHashMacAddress; 1868 p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr = DtsecDelHashMacAddress; 1869 p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr = DtsecAddExactMatchMacAddress; 1870 p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr = DtsecDelExactMatchMacAddress; 1871 p_FmMacControllerDriver->f_FM_MAC_GetId = DtsecGetId; 1872 p_FmMacControllerDriver->f_FM_MAC_GetVersion = DtsecGetVersion; 1873 p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength = DtsecGetMaxFrameLength; 1874 1875 p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg = DTSEC_MII_WritePhyReg; 1876 p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg = DTSEC_MII_ReadPhyReg; 1877 1878 #if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) 1879 p_FmMacControllerDriver->f_FM_MAC_DumpRegs = DtsecDumpRegs; 1880 #endif /* (defined(DEBUG_ERRORS) && ... */ 1881 } 1882 1883 1884 /*****************************************************************************/ 1885 /* dTSEC Config Main Entry */ 1886 /*****************************************************************************/ 1887 1888 /* .............................................................................. */ 1889 1890 t_Handle DTSEC_Config(t_FmMacParams *p_FmMacParam) 1891 { 1892 t_Dtsec *p_Dtsec; 1893 t_DtsecDriverParam *p_DtsecDriverParam; 1894 uintptr_t baseAddr; 1895 uint8_t i; 1896 1897 SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_NULL_POINTER, NULL); 1898 1899 baseAddr = p_FmMacParam->baseAddr; 1900 /* allocate memory for the UCC GETH data structure. */ 1901 p_Dtsec = (t_Dtsec *) XX_Malloc(sizeof(t_Dtsec)); 1902 if (!p_Dtsec) 1903 { 1904 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("dTSEC driver structure")); 1905 return NULL; 1906 } 1907 /* Zero out * p_Dtsec */ 1908 memset(p_Dtsec, 0, sizeof(t_Dtsec)); 1909 InitFmMacControllerDriver(&p_Dtsec->fmMacControllerDriver); 1910 1911 /* allocate memory for the dTSEC driver parameters data structure. */ 1912 p_DtsecDriverParam = (t_DtsecDriverParam *) XX_Malloc(sizeof(t_DtsecDriverParam)); 1913 if (!p_DtsecDriverParam) 1914 { 1915 XX_Free(p_Dtsec); 1916 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("dTSEC driver parameters")); 1917 return NULL; 1918 } 1919 /* Zero out */ 1920 memset(p_DtsecDriverParam, 0, sizeof(t_DtsecDriverParam)); 1921 1922 /* Plant parameter structure pointer */ 1923 p_Dtsec->p_DtsecDriverParam = p_DtsecDriverParam; 1924 1925 SetDefaultParam(p_DtsecDriverParam); 1926 1927 for (i=0; i < sizeof(p_FmMacParam->addr); i++) 1928 p_Dtsec->addr |= ((uint64_t)p_FmMacParam->addr[i] << ((5-i) * 8)); 1929 1930 p_Dtsec->p_MemMap = (t_DtsecMemMap *)UINT_TO_PTR(baseAddr); 1931 p_Dtsec->p_MiiMemMap = (t_MiiAccessMemMap *)UINT_TO_PTR(baseAddr + DTSEC_TO_MII_OFFSET); 1932 p_Dtsec->enetMode = p_FmMacParam->enetMode; 1933 p_Dtsec->macId = p_FmMacParam->macId; 1934 p_Dtsec->exceptions = DEFAULT_exceptions; 1935 p_Dtsec->mdioIrq = p_FmMacParam->mdioIrq; 1936 p_Dtsec->f_Exception = p_FmMacParam->f_Exception; 1937 p_Dtsec->f_Event = p_FmMacParam->f_Event; 1938 p_Dtsec->h_App = p_FmMacParam->h_App; 1939 1940 return p_Dtsec; 1941 } 1942