1 /* 2 * Copyright 2008-2012 Freescale Semiconductor Inc. 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 /****************************************************************************** 35 @File memac.c 36 37 @Description FM mEMAC driver 38 *//***************************************************************************/ 39 40 #include "std_ext.h" 41 #include "string_ext.h" 42 #include "error_ext.h" 43 #include "xx_ext.h" 44 #include "endian_ext.h" 45 #include "debug_ext.h" 46 47 #include "fm_common.h" 48 #include "memac.h" 49 50 51 /*****************************************************************************/ 52 /* Internal routines */ 53 /*****************************************************************************/ 54 55 /* ......................................................................... */ 56 57 static uint32_t GetMacAddrHashCode(uint64_t ethAddr) 58 { 59 uint64_t mask1, mask2; 60 uint32_t xorVal = 0; 61 uint8_t i, j; 62 63 for (i=0; i<6; i++) 64 { 65 mask1 = ethAddr & (uint64_t)0x01; 66 ethAddr >>= 1; 67 68 for (j=0; j<7; j++) 69 { 70 mask2 = ethAddr & (uint64_t)0x01; 71 mask1 ^= mask2; 72 ethAddr >>= 1; 73 } 74 75 xorVal |= (mask1 << (5-i)); 76 } 77 78 return xorVal; 79 } 80 81 /* ......................................................................... */ 82 83 static void SetupSgmiiInternalPhy(t_Memac *p_Memac, uint8_t phyAddr) 84 { 85 uint16_t tmpReg16; 86 e_EnetMode enetMode; 87 88 /* In case the higher MACs are used (i.e. the MACs that should support 10G), 89 speed=10000 is provided for SGMII ports. Temporary modify enet mode 90 to 1G one, so MII functions can work correctly. */ 91 enetMode = p_Memac->enetMode; 92 93 /* SGMII mode + AN enable */ 94 tmpReg16 = PHY_SGMII_IF_MODE_AN | PHY_SGMII_IF_MODE_SGMII; 95 if ((p_Memac->enetMode) == e_ENET_MODE_SGMII_2500) 96 tmpReg16 = PHY_SGMII_CR_PHY_RESET | PHY_SGMII_IF_SPEED_GIGABIT | PHY_SGMII_IF_MODE_SGMII; 97 98 p_Memac->enetMode = MAKE_ENET_MODE(ENET_INTERFACE_FROM_MODE(p_Memac->enetMode), e_ENET_SPEED_1000); 99 MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x14, tmpReg16); 100 101 /* Device ability according to SGMII specification */ 102 tmpReg16 = PHY_SGMII_DEV_ABILITY_SGMII; 103 MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x4, tmpReg16); 104 105 /* Adjust link timer for SGMII - 106 According to Cisco SGMII specification the timer should be 1.6 ms. 107 The link_timer register is configured in units of the clock. 108 - When running as 1G SGMII, Serdes clock is 125 MHz, so 109 unit = 1 / (125*10^6 Hz) = 8 ns. 110 1.6 ms in units of 8 ns = 1.6ms / 8ns = 2 * 10^5 = 0x30d40 111 - When running as 2.5G SGMII, Serdes clock is 312.5 MHz, so 112 unit = 1 / (312.5*10^6 Hz) = 3.2 ns. 113 1.6 ms in units of 3.2 ns = 1.6ms / 3.2ns = 5 * 10^5 = 0x7a120. 114 Since link_timer value of 1G SGMII will be too short for 2.5 SGMII, 115 we always set up here a value of 2.5 SGMII. */ 116 MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x13, 0x0007); 117 MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x12, 0xa120); 118 119 /* Restart AN */ 120 tmpReg16 = PHY_SGMII_CR_DEF_VAL | PHY_SGMII_CR_RESET_AN; 121 MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x0, tmpReg16); 122 123 /* Restore original enet mode */ 124 p_Memac->enetMode = enetMode; 125 } 126 127 /* ......................................................................... */ 128 129 static void SetupSgmiiInternalPhyBaseX(t_Memac *p_Memac, uint8_t phyAddr) 130 { 131 uint16_t tmpReg16; 132 e_EnetMode enetMode; 133 134 /* In case the higher MACs are used (i.e. the MACs that should support 10G), 135 speed=10000 is provided for SGMII ports. Temporary modify enet mode 136 to 1G one, so MII functions can work correctly. */ 137 enetMode = p_Memac->enetMode; 138 p_Memac->enetMode = MAKE_ENET_MODE(ENET_INTERFACE_FROM_MODE(p_Memac->enetMode), e_ENET_SPEED_1000); 139 140 /* 1000BaseX mode */ 141 tmpReg16 = PHY_SGMII_IF_MODE_1000X; 142 MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x14, tmpReg16); 143 144 /* AN Device capability */ 145 tmpReg16 = PHY_SGMII_DEV_ABILITY_1000X; 146 MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x4, tmpReg16); 147 148 /* Adjust link timer for SGMII - 149 For Serdes 1000BaseX auto-negotiation the timer should be 10 ms. 150 The link_timer register is configured in units of the clock. 151 - When running as 1G SGMII, Serdes clock is 125 MHz, so 152 unit = 1 / (125*10^6 Hz) = 8 ns. 153 10 ms in units of 8 ns = 10ms / 8ns = 1250000 = 0x1312d0 154 - When running as 2.5G SGMII, Serdes clock is 312.5 MHz, so 155 unit = 1 / (312.5*10^6 Hz) = 3.2 ns. 156 10 ms in units of 3.2 ns = 10ms / 3.2ns = 3125000 = 0x2faf08. 157 Since link_timer value of 1G SGMII will be too short for 2.5 SGMII, 158 we always set up here a value of 2.5 SGMII. */ 159 MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x13, 0x002f); 160 MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x12, 0xaf08); 161 162 /* Restart AN */ 163 tmpReg16 = PHY_SGMII_CR_DEF_VAL | PHY_SGMII_CR_RESET_AN; 164 MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x0, tmpReg16); 165 166 /* Restore original enet mode */ 167 p_Memac->enetMode = enetMode; 168 } 169 170 /* ......................................................................... */ 171 172 static t_Error CheckInitParameters(t_Memac *p_Memac) 173 { 174 e_FmMacType portType; 175 176 portType = ((ENET_SPEED_FROM_MODE(p_Memac->enetMode) < e_ENET_SPEED_10000) ? e_FM_MAC_1G : e_FM_MAC_10G); 177 178 #if (FM_MAX_NUM_OF_10G_MACS > 0) 179 if ((portType == e_FM_MAC_10G) && (p_Memac->macId >= FM_MAX_NUM_OF_10G_MACS)) 180 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("10G MAC ID must be less than %d", FM_MAX_NUM_OF_10G_MACS)); 181 #endif /* (FM_MAX_NUM_OF_10G_MACS > 0) */ 182 183 if ((portType == e_FM_MAC_1G) && (p_Memac->macId >= FM_MAX_NUM_OF_1G_MACS)) 184 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("1G MAC ID must be less than %d", FM_MAX_NUM_OF_1G_MACS)); 185 if (p_Memac->addr == 0) 186 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet MAC must have a valid MAC address")); 187 if (!p_Memac->f_Exception) 188 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Uninitialized f_Exception")); 189 if (!p_Memac->f_Event) 190 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Uninitialized f_Event")); 191 #ifdef FM_LEN_CHECK_ERRATA_FMAN_SW002 192 if (!p_Memac->p_MemacDriverParam->no_length_check_enable) 193 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("LengthCheck!")); 194 #endif /* FM_LEN_CHECK_ERRATA_FMAN_SW002 */ 195 196 return E_OK; 197 } 198 199 /* ........................................................................... */ 200 201 static void MemacErrException(t_Handle h_Memac) 202 { 203 t_Memac *p_Memac = (t_Memac *)h_Memac; 204 uint32_t event, imask; 205 206 event = fman_memac_get_event(p_Memac->p_MemMap, 0xffffffff); 207 imask = fman_memac_get_interrupt_mask(p_Memac->p_MemMap); 208 209 /* Imask include both error and notification/event bits. 210 Leaving only error bits enabled by imask. 211 The imask error bits are shifted by 16 bits offset from 212 their corresponding location in the ievent - hence the >> 16 */ 213 event &= ((imask & MEMAC_ALL_ERRS_IMASK) >> 16); 214 215 fman_memac_ack_event(p_Memac->p_MemMap, event); 216 217 if (event & MEMAC_IEVNT_TS_ECC_ER) 218 p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_TS_FIFO_ECC_ERR); 219 if (event & MEMAC_IEVNT_TX_ECC_ER) 220 p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_10G_1TX_ECC_ER); 221 if (event & MEMAC_IEVNT_RX_ECC_ER) 222 p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_10G_RX_ECC_ER); 223 } 224 225 static void MemacException(t_Handle h_Memac) 226 { 227 t_Memac *p_Memac = (t_Memac *)h_Memac; 228 uint32_t event, imask; 229 230 event = fman_memac_get_event(p_Memac->p_MemMap, 0xffffffff); 231 imask = fman_memac_get_interrupt_mask(p_Memac->p_MemMap); 232 233 /* Imask include both error and notification/event bits. 234 Leaving only error bits enabled by imask. 235 The imask error bits are shifted by 16 bits offset from 236 their corresponding location in the ievent - hence the >> 16 */ 237 event &= ((imask & MEMAC_ALL_ERRS_IMASK) >> 16); 238 239 fman_memac_ack_event(p_Memac->p_MemMap, event); 240 241 if (event & MEMAC_IEVNT_MGI) 242 p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_MAGIC_PACKET_INDICATION); 243 } 244 245 /* ......................................................................... */ 246 247 static void FreeInitResources(t_Memac *p_Memac) 248 { 249 e_FmMacType portType; 250 251 portType = 252 ((ENET_SPEED_FROM_MODE(p_Memac->enetMode) < e_ENET_SPEED_10000) ? e_FM_MAC_1G : e_FM_MAC_10G); 253 254 if (portType == e_FM_MAC_10G) 255 FmUnregisterIntr(p_Memac->fmMacControllerDriver.h_Fm, e_FM_MOD_10G_MAC, p_Memac->macId, e_FM_INTR_TYPE_ERR); 256 else 257 FmUnregisterIntr(p_Memac->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Memac->macId, e_FM_INTR_TYPE_ERR); 258 259 /* release the driver's group hash table */ 260 FreeHashTable(p_Memac->p_MulticastAddrHash); 261 p_Memac->p_MulticastAddrHash = NULL; 262 263 /* release the driver's individual hash table */ 264 FreeHashTable(p_Memac->p_UnicastAddrHash); 265 p_Memac->p_UnicastAddrHash = NULL; 266 } 267 268 269 /*****************************************************************************/ 270 /* mEMAC API routines */ 271 /*****************************************************************************/ 272 273 /* ......................................................................... */ 274 275 static t_Error MemacEnable(t_Handle h_Memac, e_CommMode mode) 276 { 277 t_Memac *p_Memac = (t_Memac *)h_Memac; 278 279 SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); 280 SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); 281 282 fman_memac_enable(p_Memac->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX)); 283 284 return E_OK; 285 } 286 287 /* ......................................................................... */ 288 289 static t_Error MemacDisable (t_Handle h_Memac, e_CommMode mode) 290 { 291 t_Memac *p_Memac = (t_Memac *)h_Memac; 292 293 SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); 294 SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); 295 296 fman_memac_disable(p_Memac->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX)); 297 298 return E_OK; 299 } 300 301 /* ......................................................................... */ 302 303 static t_Error MemacSetPromiscuous(t_Handle h_Memac, bool newVal) 304 { 305 t_Memac *p_Memac = (t_Memac *)h_Memac; 306 307 SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); 308 SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); 309 310 fman_memac_set_promiscuous(p_Memac->p_MemMap, newVal); 311 312 return E_OK; 313 } 314 315 /* .............................................................................. */ 316 317 static t_Error MemacAdjustLink(t_Handle h_Memac, e_EnetSpeed speed, bool fullDuplex) 318 { 319 t_Memac *p_Memac = (t_Memac *)h_Memac; 320 321 SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); 322 SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); 323 324 if ((speed >= e_ENET_SPEED_1000) && (!fullDuplex)) 325 RETURN_ERROR(MAJOR, E_CONFLICT, 326 ("Ethernet MAC 1G or 10G does not support half-duplex")); 327 328 fman_memac_adjust_link(p_Memac->p_MemMap, 329 (enum enet_interface)ENET_INTERFACE_FROM_MODE(p_Memac->enetMode), 330 (enum enet_speed)speed, 331 fullDuplex); 332 return E_OK; 333 } 334 335 336 /*****************************************************************************/ 337 /* Memac Configs modification functions */ 338 /*****************************************************************************/ 339 340 /* ......................................................................... */ 341 342 static t_Error MemacConfigLoopback(t_Handle h_Memac, bool newVal) 343 { 344 t_Memac *p_Memac = (t_Memac *)h_Memac; 345 346 SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); 347 SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE); 348 349 p_Memac->p_MemacDriverParam->loopback_enable = newVal; 350 351 return E_OK; 352 } 353 354 /* ......................................................................... */ 355 356 static t_Error MemacConfigWan(t_Handle h_Memac, bool newVal) 357 { 358 t_Memac *p_Memac = (t_Memac *)h_Memac; 359 360 SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); 361 SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE); 362 363 p_Memac->p_MemacDriverParam->wan_mode_enable = newVal; 364 365 return E_OK; 366 } 367 368 /* ......................................................................... */ 369 370 static t_Error MemacConfigMaxFrameLength(t_Handle h_Memac, uint16_t newVal) 371 { 372 t_Memac *p_Memac = (t_Memac *)h_Memac; 373 374 SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); 375 SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE); 376 377 p_Memac->p_MemacDriverParam->max_frame_length = newVal; 378 379 return E_OK; 380 } 381 382 /* ......................................................................... */ 383 384 static t_Error MemacConfigPad(t_Handle h_Memac, bool newVal) 385 { 386 t_Memac *p_Memac = (t_Memac *)h_Memac; 387 388 SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); 389 SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE); 390 391 p_Memac->p_MemacDriverParam->pad_enable = newVal; 392 393 return E_OK; 394 } 395 396 /* ......................................................................... */ 397 398 static t_Error MemacConfigLengthCheck(t_Handle h_Memac, bool newVal) 399 { 400 t_Memac *p_Memac = (t_Memac *)h_Memac; 401 402 SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); 403 SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE); 404 405 p_Memac->p_MemacDriverParam->no_length_check_enable = !newVal; 406 407 return E_OK; 408 } 409 410 /* ......................................................................... */ 411 412 static t_Error MemacConfigException(t_Handle h_Memac, e_FmMacExceptions exception, bool enable) 413 { 414 t_Memac *p_Memac = (t_Memac *)h_Memac; 415 uint32_t bitMask = 0; 416 417 SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); 418 SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE); 419 420 GET_EXCEPTION_FLAG(bitMask, exception); 421 if (bitMask) 422 { 423 if (enable) 424 p_Memac->exceptions |= bitMask; 425 else 426 p_Memac->exceptions &= ~bitMask; 427 } 428 else 429 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception")); 430 431 return E_OK; 432 } 433 434 /* ......................................................................... */ 435 436 static t_Error MemacConfigResetOnInit(t_Handle h_Memac, bool enable) 437 { 438 t_Memac *p_Memac = (t_Memac *)h_Memac; 439 440 SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); 441 SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE); 442 443 p_Memac->p_MemacDriverParam->reset_on_init = enable; 444 445 return E_OK; 446 } 447 448 449 /*****************************************************************************/ 450 /* Memac Run Time API functions */ 451 /*****************************************************************************/ 452 453 /* ......................................................................... */ 454 455 static t_Error MemacSetTxPauseFrames(t_Handle h_Memac, 456 uint8_t priority, 457 uint16_t pauseTime, 458 uint16_t threshTime) 459 { 460 t_Memac *p_Memac = (t_Memac *)h_Memac; 461 462 SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_STATE); 463 SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); 464 465 if (priority != 0xFF) 466 { 467 bool PortConfigured, PreFetchEnabled; 468 469 if (FmGetTnumAgingPeriod(p_Memac->fmMacControllerDriver.h_Fm) == 0) 470 RETURN_ERROR(MAJOR, E_CONFLICT, ("For PFC operation, TNUM aging must be enabled")); 471 472 FmGetPortPreFetchConfiguration(p_Memac->fmMacControllerDriver.h_Fm, 473 p_Memac->fmMacControllerDriver.macId, 474 &PortConfigured, 475 &PreFetchEnabled); 476 477 if ((ENET_SPEED_FROM_MODE(p_Memac->fmMacControllerDriver.enetMode) == e_ENET_SPEED_1000) && !PortConfigured) 478 DBG(INFO, ("For PFC correct operation, prefetch must be configured on the FM Tx PORT")); 479 480 if ((ENET_SPEED_FROM_MODE(p_Memac->fmMacControllerDriver.enetMode) == e_ENET_SPEED_1000) && PortConfigured && !PreFetchEnabled) 481 DBG(WARNING, ("For PFC correct operation, prefetch must be configured on the FM Tx PORT")); 482 } 483 484 fman_memac_set_tx_pause_frames(p_Memac->p_MemMap, priority, pauseTime, threshTime); 485 486 return E_OK; 487 } 488 489 /* ......................................................................... */ 490 491 static t_Error MemacSetTxAutoPauseFrames(t_Handle h_Memac, 492 uint16_t pauseTime) 493 { 494 return MemacSetTxPauseFrames(h_Memac, FM_MAC_NO_PFC, pauseTime, 0); 495 } 496 497 /* ......................................................................... */ 498 499 static t_Error MemacSetRxIgnorePauseFrames(t_Handle h_Memac, bool en) 500 { 501 t_Memac *p_Memac = (t_Memac *)h_Memac; 502 503 SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_STATE); 504 SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); 505 506 fman_memac_set_rx_ignore_pause_frames(p_Memac->p_MemMap, en); 507 508 return E_OK; 509 } 510 511 /* ......................................................................... */ 512 513 static t_Error MemacSetWakeOnLan(t_Handle h_Memac, bool en) 514 { 515 t_Memac *p_Memac = (t_Memac *)h_Memac; 516 517 SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_STATE); 518 SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); 519 520 fman_memac_set_wol(p_Memac->p_MemMap, en); 521 522 return E_OK; 523 } 524 525 /* .............................................................................. */ 526 527 static t_Error MemacEnable1588TimeStamp(t_Handle h_Memac) 528 { 529 t_Memac *p_Memac = (t_Memac *)h_Memac; 530 531 SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); 532 SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); 533 UNUSED(p_Memac); 534 DBG(WARNING, ("mEMAC has 1588 always enabled!")); 535 536 return E_OK; 537 } 538 539 /* Counters handling */ 540 /* ......................................................................... */ 541 542 static t_Error MemacGetStatistics(t_Handle h_Memac, t_FmMacStatistics *p_Statistics) 543 { 544 t_Memac *p_Memac = (t_Memac *)h_Memac; 545 546 SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER); 547 SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); 548 SANITY_CHECK_RETURN_ERROR(p_Statistics, E_NULL_POINTER); 549 550 p_Statistics->eStatPkts64 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R64); 551 p_Statistics->eStatPkts65to127 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R127); 552 p_Statistics->eStatPkts128to255 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R255); 553 p_Statistics->eStatPkts256to511 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R511); 554 p_Statistics->eStatPkts512to1023 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1023); 555 p_Statistics->eStatPkts1024to1518 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1518); 556 p_Statistics->eStatPkts1519to1522 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1519X); 557 /* */ 558 p_Statistics->eStatFragments = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RFRG); 559 p_Statistics->eStatJabbers = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RJBR); 560 561 p_Statistics->eStatsDropEvents = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RDRP); 562 p_Statistics->eStatCRCAlignErrors = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RALN); 563 564 p_Statistics->eStatUndersizePkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TUND); 565 p_Statistics->eStatOversizePkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_ROVR); 566 /* Pause */ 567 p_Statistics->reStatPause = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RXPF); 568 p_Statistics->teStatPause = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TXPF); 569 570 /* MIB II */ 571 p_Statistics->ifInOctets = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_ROCT); 572 p_Statistics->ifInUcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RUCA); 573 p_Statistics->ifInMcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RMCA); 574 p_Statistics->ifInBcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RBCA); 575 p_Statistics->ifInPkts = p_Statistics->ifInUcastPkts 576 + p_Statistics->ifInMcastPkts 577 + p_Statistics->ifInBcastPkts; 578 p_Statistics->ifInDiscards = 0; 579 p_Statistics->ifInErrors = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RERR); 580 581 p_Statistics->ifOutOctets = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TOCT); 582 p_Statistics->ifOutUcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TUCA); 583 p_Statistics->ifOutMcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TMCA); 584 p_Statistics->ifOutBcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TBCA); 585 p_Statistics->ifOutPkts = p_Statistics->ifOutUcastPkts 586 + p_Statistics->ifOutMcastPkts 587 + p_Statistics->ifOutBcastPkts; 588 p_Statistics->ifOutDiscards = 0; 589 p_Statistics->ifOutErrors = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TERR); 590 591 return E_OK; 592 } 593 594 /* ......................................................................... */ 595 596 static t_Error MemacModifyMacAddress (t_Handle h_Memac, t_EnetAddr *p_EnetAddr) 597 { 598 t_Memac *p_Memac = (t_Memac *)h_Memac; 599 600 SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER); 601 SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); 602 603 fman_memac_add_addr_in_paddr(p_Memac->p_MemMap, (uint8_t *)(*p_EnetAddr), 0); 604 605 return E_OK; 606 } 607 608 /* ......................................................................... */ 609 610 static t_Error MemacResetCounters (t_Handle h_Memac) 611 { 612 t_Memac *p_Memac = (t_Memac *)h_Memac; 613 614 SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); 615 SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); 616 617 fman_memac_reset_stat(p_Memac->p_MemMap); 618 619 return E_OK; 620 } 621 622 /* ......................................................................... */ 623 624 static t_Error MemacAddExactMatchMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr) 625 { 626 t_Memac *p_Memac = (t_Memac *) h_Memac; 627 uint64_t ethAddr; 628 uint8_t paddrNum; 629 630 SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); 631 SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); 632 633 ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr); 634 635 if (ethAddr & GROUP_ADDRESS) 636 /* Multicast address has no effect in PADDR */ 637 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Multicast address")); 638 639 /* Make sure no PADDR contains this address */ 640 for (paddrNum = 0; paddrNum < MEMAC_NUM_OF_PADDRS; paddrNum++) 641 if (p_Memac->indAddrRegUsed[paddrNum]) 642 if (p_Memac->paddr[paddrNum] == ethAddr) 643 RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG); 644 645 /* Find first unused PADDR */ 646 for (paddrNum = 0; paddrNum < MEMAC_NUM_OF_PADDRS; paddrNum++) 647 if (!(p_Memac->indAddrRegUsed[paddrNum])) 648 { 649 /* mark this PADDR as used */ 650 p_Memac->indAddrRegUsed[paddrNum] = TRUE; 651 /* store address */ 652 p_Memac->paddr[paddrNum] = ethAddr; 653 654 /* put in hardware */ 655 fman_memac_add_addr_in_paddr(p_Memac->p_MemMap, (uint8_t*)(*p_EthAddr), paddrNum); 656 p_Memac->numOfIndAddrInRegs++; 657 658 return E_OK; 659 } 660 661 /* No free PADDR */ 662 RETURN_ERROR(MAJOR, E_FULL, NO_MSG); 663 } 664 665 /* ......................................................................... */ 666 667 static t_Error MemacDelExactMatchMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr) 668 { 669 t_Memac *p_Memac = (t_Memac *) h_Memac; 670 uint64_t ethAddr; 671 uint8_t paddrNum; 672 673 SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); 674 SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); 675 676 ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr); 677 678 /* Find used PADDR containing this address */ 679 for (paddrNum = 0; paddrNum < MEMAC_NUM_OF_PADDRS; paddrNum++) 680 { 681 if ((p_Memac->indAddrRegUsed[paddrNum]) && 682 (p_Memac->paddr[paddrNum] == ethAddr)) 683 { 684 /* mark this PADDR as not used */ 685 p_Memac->indAddrRegUsed[paddrNum] = FALSE; 686 /* clear in hardware */ 687 fman_memac_clear_addr_in_paddr(p_Memac->p_MemMap, paddrNum); 688 p_Memac->numOfIndAddrInRegs--; 689 690 return E_OK; 691 } 692 } 693 694 RETURN_ERROR(MAJOR, E_NOT_FOUND, NO_MSG); 695 } 696 697 /* ......................................................................... */ 698 699 static t_Error MemacGetId(t_Handle h_Memac, uint32_t *macId) 700 { 701 t_Memac *p_Memac = (t_Memac *)h_Memac; 702 703 SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); 704 SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); 705 706 *macId = p_Memac->macId; 707 708 return E_OK; 709 } 710 711 /* ......................................................................... */ 712 713 714 static t_Error MemacAddHashMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr) 715 { 716 t_Memac *p_Memac = (t_Memac *)h_Memac; 717 t_EthHashEntry *p_HashEntry; 718 uint32_t hash; 719 uint64_t ethAddr; 720 721 SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER); 722 SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); 723 724 ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr); 725 726 if (!(ethAddr & GROUP_ADDRESS)) 727 /* Unicast addresses not supported in hash */ 728 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unicast Address")); 729 730 hash = GetMacAddrHashCode(ethAddr) & HASH_CTRL_ADDR_MASK; 731 732 /* Create element to be added to the driver hash table */ 733 p_HashEntry = (t_EthHashEntry *)XX_Malloc(sizeof(t_EthHashEntry)); 734 p_HashEntry->addr = ethAddr; 735 INIT_LIST(&p_HashEntry->node); 736 737 LIST_AddToTail(&(p_HashEntry->node), &(p_Memac->p_MulticastAddrHash->p_Lsts[hash])); 738 fman_memac_set_hash_table(p_Memac->p_MemMap, (hash | HASH_CTRL_MCAST_EN)); 739 740 return E_OK; 741 } 742 743 /* ......................................................................... */ 744 745 static t_Error MemacDelHashMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr) 746 { 747 t_Memac *p_Memac = (t_Memac *)h_Memac; 748 t_EthHashEntry *p_HashEntry = NULL; 749 t_List *p_Pos; 750 uint32_t hash; 751 uint64_t ethAddr; 752 753 SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER); 754 SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); 755 756 ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr); 757 758 hash = GetMacAddrHashCode(ethAddr) & HASH_CTRL_ADDR_MASK; 759 760 LIST_FOR_EACH(p_Pos, &(p_Memac->p_MulticastAddrHash->p_Lsts[hash])) 761 { 762 p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos); 763 if (p_HashEntry->addr == ethAddr) 764 { 765 LIST_DelAndInit(&p_HashEntry->node); 766 XX_Free(p_HashEntry); 767 break; 768 } 769 } 770 if (LIST_IsEmpty(&p_Memac->p_MulticastAddrHash->p_Lsts[hash])) 771 fman_memac_set_hash_table(p_Memac->p_MemMap, (hash & ~HASH_CTRL_MCAST_EN)); 772 773 return E_OK; 774 } 775 776 777 /* ......................................................................... */ 778 779 static t_Error MemacSetException(t_Handle h_Memac, e_FmMacExceptions exception, bool enable) 780 { 781 t_Memac *p_Memac = (t_Memac *)h_Memac; 782 uint32_t bitMask = 0; 783 784 SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); 785 SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); 786 787 GET_EXCEPTION_FLAG(bitMask, exception); 788 if (bitMask) 789 { 790 if (enable) 791 p_Memac->exceptions |= bitMask; 792 else 793 p_Memac->exceptions &= ~bitMask; 794 } 795 else 796 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception")); 797 798 fman_memac_set_exception(p_Memac->p_MemMap, bitMask, enable); 799 800 return E_OK; 801 } 802 803 /* ......................................................................... */ 804 805 static uint16_t MemacGetMaxFrameLength(t_Handle h_Memac) 806 { 807 t_Memac *p_Memac = (t_Memac *)h_Memac; 808 809 SANITY_CHECK_RETURN_VALUE(p_Memac, E_INVALID_HANDLE, 0); 810 SANITY_CHECK_RETURN_VALUE(!p_Memac->p_MemacDriverParam, E_INVALID_STATE, 0); 811 812 return fman_memac_get_max_frame_len(p_Memac->p_MemMap); 813 } 814 815 static t_Error MemacInitInternalPhy(t_Handle h_Memac) 816 { 817 t_Memac *p_Memac = (t_Memac *)h_Memac; 818 uint8_t i, phyAddr; 819 820 if (ENET_INTERFACE_FROM_MODE(p_Memac->enetMode) == e_ENET_IF_SGMII) 821 { 822 /* Configure internal SGMII PHY */ 823 if (p_Memac->enetMode & ENET_IF_SGMII_BASEX) 824 SetupSgmiiInternalPhyBaseX(p_Memac, PHY_MDIO_ADDR); 825 else 826 SetupSgmiiInternalPhy(p_Memac, PHY_MDIO_ADDR); 827 } 828 else if (ENET_INTERFACE_FROM_MODE(p_Memac->enetMode) == e_ENET_IF_QSGMII) 829 { 830 /* Configure 4 internal SGMII PHYs */ 831 for (i = 0; i < 4; i++) 832 { 833 /* QSGMII PHY address occupies 3 upper bits of 5-bit 834 phyAddress; the lower 2 bits are used to extend 835 register address space and access each one of 4 836 ports inside QSGMII. */ 837 phyAddr = (uint8_t)((PHY_MDIO_ADDR << 2) | i); 838 if (p_Memac->enetMode & ENET_IF_SGMII_BASEX) 839 SetupSgmiiInternalPhyBaseX(p_Memac, phyAddr); 840 else 841 SetupSgmiiInternalPhy(p_Memac, phyAddr); 842 } 843 } 844 return E_OK; 845 } 846 847 /*****************************************************************************/ 848 /* mEMAC Init & Free API */ 849 /*****************************************************************************/ 850 851 /* ......................................................................... */ 852 void *g_MemacRegs; 853 static t_Error MemacInit(t_Handle h_Memac) 854 { 855 t_Memac *p_Memac = (t_Memac *)h_Memac; 856 struct memac_cfg *p_MemacDriverParam; 857 enum enet_interface enet_interface; 858 enum enet_speed enet_speed; 859 t_EnetAddr ethAddr; 860 e_FmMacType portType; 861 t_Error err; 862 bool slow_10g_if = FALSE; 863 if (p_Memac->macId == 3) /* This is a quick WA */ 864 g_MemacRegs = p_Memac->p_MemMap; 865 866 SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); 867 SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE); 868 SANITY_CHECK_RETURN_ERROR(p_Memac->fmMacControllerDriver.h_Fm, E_INVALID_HANDLE); 869 870 FM_GetRevision(p_Memac->fmMacControllerDriver.h_Fm, &p_Memac->fmMacControllerDriver.fmRevInfo); 871 if (p_Memac->fmMacControllerDriver.fmRevInfo.majorRev == 6 && 872 p_Memac->fmMacControllerDriver.fmRevInfo.minorRev == 4) 873 slow_10g_if = TRUE; 874 875 CHECK_INIT_PARAMETERS(p_Memac, CheckInitParameters); 876 877 p_MemacDriverParam = p_Memac->p_MemacDriverParam; 878 879 portType = 880 ((ENET_SPEED_FROM_MODE(p_Memac->enetMode) < e_ENET_SPEED_10000) ? e_FM_MAC_1G : e_FM_MAC_10G); 881 882 /* First, reset the MAC if desired. */ 883 if (p_MemacDriverParam->reset_on_init) 884 fman_memac_reset(p_Memac->p_MemMap); 885 886 /* MAC Address */ 887 MAKE_ENET_ADDR_FROM_UINT64(p_Memac->addr, ethAddr); 888 fman_memac_add_addr_in_paddr(p_Memac->p_MemMap, (uint8_t*)ethAddr, 0); 889 890 enet_interface = (enum enet_interface) ENET_INTERFACE_FROM_MODE(p_Memac->enetMode); 891 enet_speed = (enum enet_speed) ENET_SPEED_FROM_MODE(p_Memac->enetMode); 892 893 fman_memac_init(p_Memac->p_MemMap, 894 p_Memac->p_MemacDriverParam, 895 enet_interface, 896 enet_speed, 897 slow_10g_if, 898 p_Memac->exceptions); 899 900 #ifdef FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320 901 { 902 uint32_t tmpReg = 0; 903 904 FM_GetRevision(p_Memac->fmMacControllerDriver.h_Fm, &p_Memac->fmMacControllerDriver.fmRevInfo); 905 /* check the FMAN version - the bug exists only in rev1 */ 906 if ((p_Memac->fmMacControllerDriver.fmRevInfo.majorRev == 6) && 907 (p_Memac->fmMacControllerDriver.fmRevInfo.minorRev == 0)) 908 { 909 /* MAC strips CRC from received frames - this workaround should 910 decrease the likelihood of bug appearance 911 */ 912 tmpReg = GET_UINT32(p_Memac->p_MemMap->command_config); 913 tmpReg &= ~CMD_CFG_CRC_FWD; 914 WRITE_UINT32(p_Memac->p_MemMap->command_config, tmpReg); 915 /* DBG(WARNING, ("mEMAC strips CRC from received frames as part of A006320 errata workaround"));*/ 916 } 917 } 918 #endif /* FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320 */ 919 920 MemacInitInternalPhy(h_Memac); 921 922 /* Max Frame Length */ 923 err = FmSetMacMaxFrame(p_Memac->fmMacControllerDriver.h_Fm, 924 portType, 925 p_Memac->fmMacControllerDriver.macId, 926 p_MemacDriverParam->max_frame_length); 927 if (err) 928 RETURN_ERROR(MAJOR, err, ("settings Mac max frame length is FAILED")); 929 930 p_Memac->p_MulticastAddrHash = AllocHashTable(HASH_TABLE_SIZE); 931 if (!p_Memac->p_MulticastAddrHash) 932 { 933 FreeInitResources(p_Memac); 934 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED")); 935 } 936 937 p_Memac->p_UnicastAddrHash = AllocHashTable(HASH_TABLE_SIZE); 938 if (!p_Memac->p_UnicastAddrHash) 939 { 940 FreeInitResources(p_Memac); 941 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED")); 942 } 943 944 FmRegisterIntr(p_Memac->fmMacControllerDriver.h_Fm, 945 (portType == e_FM_MAC_10G) ? e_FM_MOD_10G_MAC : e_FM_MOD_1G_MAC, 946 p_Memac->macId, 947 e_FM_INTR_TYPE_ERR, 948 MemacErrException, 949 p_Memac); 950 951 FmRegisterIntr(p_Memac->fmMacControllerDriver.h_Fm, 952 (portType == e_FM_MAC_10G) ? e_FM_MOD_10G_MAC : e_FM_MOD_1G_MAC, 953 p_Memac->macId, 954 e_FM_INTR_TYPE_NORMAL, 955 MemacException, 956 p_Memac); 957 958 XX_Free(p_MemacDriverParam); 959 p_Memac->p_MemacDriverParam = NULL; 960 961 return E_OK; 962 } 963 964 /* ......................................................................... */ 965 966 static t_Error MemacFree(t_Handle h_Memac) 967 { 968 t_Memac *p_Memac = (t_Memac *)h_Memac; 969 970 SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); 971 972 if (p_Memac->p_MemacDriverParam) 973 { 974 /* Called after config */ 975 XX_Free(p_Memac->p_MemacDriverParam); 976 p_Memac->p_MemacDriverParam = NULL; 977 } 978 else 979 /* Called after init */ 980 FreeInitResources(p_Memac); 981 982 XX_Free(p_Memac); 983 984 return E_OK; 985 } 986 987 /* ......................................................................... */ 988 989 static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacControllerDriver) 990 { 991 p_FmMacControllerDriver->f_FM_MAC_Init = MemacInit; 992 p_FmMacControllerDriver->f_FM_MAC_Free = MemacFree; 993 994 p_FmMacControllerDriver->f_FM_MAC_SetStatistics = NULL; 995 p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback = MemacConfigLoopback; 996 p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength = MemacConfigMaxFrameLength; 997 998 p_FmMacControllerDriver->f_FM_MAC_ConfigWan = MemacConfigWan; 999 1000 p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc = MemacConfigPad; 1001 p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex = NULL; /* half-duplex is detected automatically */ 1002 p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck = MemacConfigLengthCheck; 1003 1004 p_FmMacControllerDriver->f_FM_MAC_ConfigException = MemacConfigException; 1005 p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit = MemacConfigResetOnInit; 1006 1007 p_FmMacControllerDriver->f_FM_MAC_SetException = MemacSetException; 1008 1009 p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp = MemacEnable1588TimeStamp; /* always enabled */ 1010 p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp = NULL; 1011 1012 p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous = MemacSetPromiscuous; 1013 p_FmMacControllerDriver->f_FM_MAC_AdjustLink = MemacAdjustLink; 1014 p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg = NULL; 1015 1016 p_FmMacControllerDriver->f_FM_MAC_Enable = MemacEnable; 1017 p_FmMacControllerDriver->f_FM_MAC_Disable = MemacDisable; 1018 p_FmMacControllerDriver->f_FM_MAC_Resume = MemacInitInternalPhy; 1019 1020 p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames = MemacSetTxAutoPauseFrames; 1021 p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames = MemacSetTxPauseFrames; 1022 p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames = MemacSetRxIgnorePauseFrames; 1023 1024 p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan = MemacSetWakeOnLan; 1025 1026 p_FmMacControllerDriver->f_FM_MAC_ResetCounters = MemacResetCounters; 1027 p_FmMacControllerDriver->f_FM_MAC_GetStatistics = MemacGetStatistics; 1028 1029 p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr = MemacModifyMacAddress; 1030 p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr = MemacAddHashMacAddress; 1031 p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr = MemacDelHashMacAddress; 1032 p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr = MemacAddExactMatchMacAddress; 1033 p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr = MemacDelExactMatchMacAddress; 1034 p_FmMacControllerDriver->f_FM_MAC_GetId = MemacGetId; 1035 p_FmMacControllerDriver->f_FM_MAC_GetVersion = NULL; 1036 p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength = MemacGetMaxFrameLength; 1037 1038 p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg = MEMAC_MII_WritePhyReg; 1039 p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg = MEMAC_MII_ReadPhyReg; 1040 } 1041 1042 1043 /*****************************************************************************/ 1044 /* mEMAC Config Main Entry */ 1045 /*****************************************************************************/ 1046 1047 /* ......................................................................... */ 1048 1049 t_Handle MEMAC_Config(t_FmMacParams *p_FmMacParam) 1050 { 1051 t_Memac *p_Memac; 1052 struct memac_cfg *p_MemacDriverParam; 1053 uintptr_t baseAddr; 1054 1055 SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_NULL_POINTER, NULL); 1056 1057 baseAddr = p_FmMacParam->baseAddr; 1058 /* Allocate memory for the mEMAC data structure */ 1059 p_Memac = (t_Memac *)XX_Malloc(sizeof(t_Memac)); 1060 if (!p_Memac) 1061 { 1062 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("mEMAC driver structure")); 1063 return NULL; 1064 } 1065 memset(p_Memac, 0, sizeof(t_Memac)); 1066 InitFmMacControllerDriver(&p_Memac->fmMacControllerDriver); 1067 1068 /* Allocate memory for the mEMAC driver parameters data structure */ 1069 p_MemacDriverParam = (struct memac_cfg *)XX_Malloc(sizeof(struct memac_cfg)); 1070 if (!p_MemacDriverParam) 1071 { 1072 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("mEMAC driver parameters")); 1073 XX_Free(p_Memac); 1074 return NULL; 1075 } 1076 memset(p_MemacDriverParam, 0, sizeof(struct memac_cfg)); 1077 1078 /* Plant parameter structure pointer */ 1079 p_Memac->p_MemacDriverParam = p_MemacDriverParam; 1080 1081 fman_memac_defconfig(p_MemacDriverParam); 1082 1083 p_Memac->addr = ENET_ADDR_TO_UINT64(p_FmMacParam->addr); 1084 1085 p_Memac->p_MemMap = (struct memac_regs *)UINT_TO_PTR(baseAddr); 1086 p_Memac->p_MiiMemMap = (struct memac_mii_access_mem_map*)UINT_TO_PTR(baseAddr + MEMAC_TO_MII_OFFSET); 1087 1088 p_Memac->enetMode = p_FmMacParam->enetMode; 1089 p_Memac->macId = p_FmMacParam->macId; 1090 p_Memac->exceptions = MEMAC_default_exceptions; 1091 p_Memac->f_Exception = p_FmMacParam->f_Exception; 1092 p_Memac->f_Event = p_FmMacParam->f_Event; 1093 p_Memac->h_App = p_FmMacParam->h_App; 1094 1095 return p_Memac; 1096 } 1097