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