Path: blob/main/sys/contrib/ncsw/Peripherals/FM/MAC/tgec.c
48524 views
/*1* Copyright 2008-2012 Freescale Semiconductor Inc.2*3* Redistribution and use in source and binary forms, with or without4* modification, are permitted provided that the following conditions are met:5* * Redistributions of source code must retain the above copyright6* notice, this list of conditions and the following disclaimer.7* * Redistributions in binary form must reproduce the above copyright8* notice, this list of conditions and the following disclaimer in the9* documentation and/or other materials provided with the distribution.10* * Neither the name of Freescale Semiconductor nor the11* names of its contributors may be used to endorse or promote products12* derived from this software without specific prior written permission.13*14*15* ALTERNATIVELY, this software may be distributed under the terms of the16* GNU General Public License ("GPL") as published by the Free Software17* Foundation, either version 2 of that License or (at your option) any18* later version.19*20* THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY21* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED22* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE23* DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY24* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES25* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;26* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND27* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT28* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS29* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.30*/313233/******************************************************************************34@File tgec.c3536@Description FM 10G MAC ...37*//***************************************************************************/3839#include "std_ext.h"40#include "string_ext.h"41#include "error_ext.h"42#include "xx_ext.h"43#include "endian_ext.h"44#include "debug_ext.h"45#include "crc_mac_addr_ext.h"4647#include "fm_common.h"48#include "fsl_fman_tgec.h"49#include "tgec.h"505152/*****************************************************************************/53/* Internal routines */54/*****************************************************************************/5556static t_Error CheckInitParameters(t_Tgec *p_Tgec)57{58if (ENET_SPEED_FROM_MODE(p_Tgec->enetMode) < e_ENET_SPEED_10000)59RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet 10G MAC driver only support 10G speed"));60#if (FM_MAX_NUM_OF_10G_MACS > 0)61if (p_Tgec->macId >= FM_MAX_NUM_OF_10G_MACS)62RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("macId of 10G can not be greater than 0"));63#endif /* (FM_MAX_NUM_OF_10G_MACS > 0) */6465if (p_Tgec->addr == 0)66RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet 10G MAC Must have a valid MAC Address"));67if (!p_Tgec->f_Exception)68RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("uninitialized f_Exception"));69if (!p_Tgec->f_Event)70RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("uninitialized f_Event"));71#ifdef FM_LEN_CHECK_ERRATA_FMAN_SW00272if (!p_Tgec->p_TgecDriverParam->no_length_check_enable)73RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("LengthCheck!"));74#endif /* FM_LEN_CHECK_ERRATA_FMAN_SW002 */75return E_OK;76}7778/* ......................................................................... */7980static uint32_t GetMacAddrHashCode(uint64_t ethAddr)81{82uint32_t crc;8384/* CRC calculation */85GET_MAC_ADDR_CRC(ethAddr, crc);8687crc = GetMirror32(crc);8889return crc;90}9192/* ......................................................................... */9394static void TgecErrException(t_Handle h_Tgec)95{96t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;97uint32_t event;98struct tgec_regs *p_TgecMemMap = p_Tgec->p_MemMap;99100/* do not handle MDIO events */101event = fman_tgec_get_event(p_TgecMemMap, ~(TGEC_IMASK_MDIO_SCAN_EVENT | TGEC_IMASK_MDIO_CMD_CMPL));102event &= fman_tgec_get_interrupt_mask(p_TgecMemMap);103104fman_tgec_ack_event(p_TgecMemMap, event);105106if (event & TGEC_IMASK_REM_FAULT)107p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_REM_FAULT);108if (event & TGEC_IMASK_LOC_FAULT)109p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_LOC_FAULT);110if (event & TGEC_IMASK_TX_ECC_ER)111p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_1TX_ECC_ER);112if (event & TGEC_IMASK_TX_FIFO_UNFL)113p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_TX_FIFO_UNFL);114if (event & TGEC_IMASK_TX_FIFO_OVFL)115p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_TX_FIFO_OVFL);116if (event & TGEC_IMASK_TX_ER)117p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_TX_ER);118if (event & TGEC_IMASK_RX_FIFO_OVFL)119p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_FIFO_OVFL);120if (event & TGEC_IMASK_RX_ECC_ER)121p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_ECC_ER);122if (event & TGEC_IMASK_RX_JAB_FRM)123p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_JAB_FRM);124if (event & TGEC_IMASK_RX_OVRSZ_FRM)125p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_OVRSZ_FRM);126if (event & TGEC_IMASK_RX_RUNT_FRM)127p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_RUNT_FRM);128if (event & TGEC_IMASK_RX_FRAG_FRM)129p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_FRAG_FRM);130if (event & TGEC_IMASK_RX_LEN_ER)131p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_LEN_ER);132if (event & TGEC_IMASK_RX_CRC_ER)133p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_CRC_ER);134if (event & TGEC_IMASK_RX_ALIGN_ER)135p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_ALIGN_ER);136}137138/* ......................................................................... */139140static void TgecException(t_Handle h_Tgec)141{142t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;143uint32_t event;144struct tgec_regs *p_TgecMemMap = p_Tgec->p_MemMap;145146/* handle only MDIO events */147event = fman_tgec_get_event(p_TgecMemMap, (TGEC_IMASK_MDIO_SCAN_EVENT | TGEC_IMASK_MDIO_CMD_CMPL));148event &= fman_tgec_get_interrupt_mask(p_TgecMemMap);149150fman_tgec_ack_event(p_TgecMemMap, event);151152if (event & TGEC_IMASK_MDIO_SCAN_EVENT)153p_Tgec->f_Event(p_Tgec->h_App, e_FM_MAC_EX_10G_MDIO_SCAN_EVENTMDIO);154if (event & TGEC_IMASK_MDIO_CMD_CMPL)155p_Tgec->f_Event(p_Tgec->h_App, e_FM_MAC_EX_10G_MDIO_CMD_CMPL);156}157158/* ......................................................................... */159160static void FreeInitResources(t_Tgec *p_Tgec)161{162if (p_Tgec->mdioIrq != NO_IRQ)163{164XX_DisableIntr(p_Tgec->mdioIrq);165XX_FreeIntr(p_Tgec->mdioIrq);166}167168FmUnregisterIntr(p_Tgec->fmMacControllerDriver.h_Fm, e_FM_MOD_10G_MAC, p_Tgec->macId, e_FM_INTR_TYPE_ERR);169170/* release the driver's group hash table */171FreeHashTable(p_Tgec->p_MulticastAddrHash);172p_Tgec->p_MulticastAddrHash = NULL;173174/* release the driver's individual hash table */175FreeHashTable(p_Tgec->p_UnicastAddrHash);176p_Tgec->p_UnicastAddrHash = NULL;177}178179180/*****************************************************************************/181/* 10G MAC API routines */182/*****************************************************************************/183184/* ......................................................................... */185186static t_Error TgecEnable(t_Handle h_Tgec, e_CommMode mode)187{188t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;189190SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);191SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);192193fman_tgec_enable(p_Tgec->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX));194195return E_OK;196}197198/* ......................................................................... */199200static t_Error TgecDisable (t_Handle h_Tgec, e_CommMode mode)201{202t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;203204SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);205SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);206207fman_tgec_disable(p_Tgec->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX));208209return E_OK;210}211212/* ......................................................................... */213214static t_Error TgecSetPromiscuous(t_Handle h_Tgec, bool newVal)215{216t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;217218SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);219SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);220221fman_tgec_set_promiscuous(p_Tgec->p_MemMap, newVal);222223return E_OK;224}225226227/*****************************************************************************/228/* Tgec Configs modification functions */229/*****************************************************************************/230231/* ......................................................................... */232233static t_Error TgecConfigLoopback(t_Handle h_Tgec, bool newVal)234{235t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;236237SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);238SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);239240p_Tgec->p_TgecDriverParam->loopback_enable = newVal;241242return E_OK;243}244245/* ......................................................................... */246247static t_Error TgecConfigWan(t_Handle h_Tgec, bool newVal)248{249t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;250251SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);252SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);253254p_Tgec->p_TgecDriverParam->wan_mode_enable = newVal;255256return E_OK;257}258259/* ......................................................................... */260261static t_Error TgecConfigMaxFrameLength(t_Handle h_Tgec, uint16_t newVal)262{263t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;264265SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);266SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);267268p_Tgec->p_TgecDriverParam->max_frame_length = newVal;269270return E_OK;271}272273/* ......................................................................... */274275static t_Error TgecConfigLengthCheck(t_Handle h_Tgec, bool newVal)276{277t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;278279UNUSED(newVal);280281SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);282SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);283284p_Tgec->p_TgecDriverParam->no_length_check_enable = !newVal;285286return E_OK;287}288289/* ......................................................................... */290291static t_Error TgecConfigException(t_Handle h_Tgec, e_FmMacExceptions exception, bool enable)292{293t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;294uint32_t bitMask = 0;295296SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);297SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);298299GET_EXCEPTION_FLAG(bitMask, exception);300if (bitMask)301{302if (enable)303p_Tgec->exceptions |= bitMask;304else305p_Tgec->exceptions &= ~bitMask;306}307else308RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));309310return E_OK;311}312313#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004314/* ......................................................................... */315316static t_Error TgecConfigSkipFman11Workaround(t_Handle h_Tgec)317{318t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;319320SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);321SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);322323p_Tgec->p_TgecDriverParam->skip_fman11_workaround = TRUE;324325return E_OK;326}327#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */328329330/*****************************************************************************/331/* Tgec Run Time API functions */332/*****************************************************************************/333334/* ......................................................................... */335/* backward compatibility. will be removed in the future. */336static t_Error TgecTxMacPause(t_Handle h_Tgec, uint16_t pauseTime)337{338t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;339340SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_STATE);341SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);342fman_tgec_set_tx_pause_frames(p_Tgec->p_MemMap, pauseTime);343344345return E_OK;346}347348/* ......................................................................... */349350static t_Error TgecSetTxPauseFrames(t_Handle h_Tgec,351uint8_t priority,352uint16_t pauseTime,353uint16_t threshTime)354{355t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;356357SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_STATE);358SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);359360UNUSED(priority); UNUSED(threshTime);361362fman_tgec_set_tx_pause_frames(p_Tgec->p_MemMap, pauseTime);363364return E_OK;365}366367/* ......................................................................... */368369static t_Error TgecRxIgnoreMacPause(t_Handle h_Tgec, bool en)370{371t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;372373SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_STATE);374SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);375376fman_tgec_set_rx_ignore_pause_frames(p_Tgec->p_MemMap, en);377378return E_OK;379}380381/* ......................................................................... */382383static t_Error TgecGetStatistics(t_Handle h_Tgec, t_FmMacStatistics *p_Statistics)384{385t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;386struct tgec_regs *p_TgecMemMap;387388SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);389SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);390SANITY_CHECK_RETURN_ERROR(p_Statistics, E_NULL_POINTER);391392p_TgecMemMap = p_Tgec->p_MemMap;393394p_Statistics->eStatPkts64 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R64);395p_Statistics->eStatPkts65to127 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R127);396p_Statistics->eStatPkts128to255 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R255);397p_Statistics->eStatPkts256to511 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R511);398p_Statistics->eStatPkts512to1023 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1023);399p_Statistics->eStatPkts1024to1518 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1518);400p_Statistics->eStatPkts1519to1522 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1519X);401/* */402p_Statistics->eStatFragments = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TRFRG);403p_Statistics->eStatJabbers = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TRJBR);404405p_Statistics->eStatsDropEvents = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RDRP);406p_Statistics->eStatCRCAlignErrors = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RALN);407408p_Statistics->eStatUndersizePkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TRUND);409p_Statistics->eStatOversizePkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TROVR);410/* Pause */411p_Statistics->reStatPause = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RXPF);412p_Statistics->teStatPause = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TXPF);413414/* MIB II */415p_Statistics->ifInOctets = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_ROCT);416p_Statistics->ifInUcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RUCA);417p_Statistics->ifInMcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RMCA);418p_Statistics->ifInBcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RBCA);419p_Statistics->ifInPkts = p_Statistics->ifInUcastPkts420+ p_Statistics->ifInMcastPkts421+ p_Statistics->ifInBcastPkts;422p_Statistics->ifInDiscards = 0;423p_Statistics->ifInErrors = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RERR);424425p_Statistics->ifOutOctets = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TOCT);426p_Statistics->ifOutUcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TUCA);427p_Statistics->ifOutMcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TMCA);428p_Statistics->ifOutBcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TBCA);429p_Statistics->ifOutPkts = p_Statistics->ifOutUcastPkts430+ p_Statistics->ifOutMcastPkts431+ p_Statistics->ifOutBcastPkts;432p_Statistics->ifOutDiscards = 0;433p_Statistics->ifOutErrors = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TERR);434435return E_OK;436}437438/* ......................................................................... */439440static t_Error TgecEnable1588TimeStamp(t_Handle h_Tgec)441{442t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;443444SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);445SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);446447fman_tgec_enable_1588_time_stamp(p_Tgec->p_MemMap, 1);448449return E_OK;450}451452/* ......................................................................... */453454static t_Error TgecDisable1588TimeStamp(t_Handle h_Tgec)455{456t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;457458SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);459SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);460461fman_tgec_enable_1588_time_stamp(p_Tgec->p_MemMap, 0);462463return E_OK;464}465466/* ......................................................................... */467468static t_Error TgecModifyMacAddress (t_Handle h_Tgec, t_EnetAddr *p_EnetAddr)469{470t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;471472SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);473SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);474475p_Tgec->addr = ENET_ADDR_TO_UINT64(*p_EnetAddr);476fman_tgec_set_mac_address(p_Tgec->p_MemMap, (uint8_t *)(*p_EnetAddr));477478return E_OK;479}480481/* ......................................................................... */482483static t_Error TgecResetCounters (t_Handle h_Tgec)484{485t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;486487SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);488SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);489490fman_tgec_reset_stat(p_Tgec->p_MemMap);491492return E_OK;493}494495/* ......................................................................... */496497static t_Error TgecAddExactMatchMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr)498{499t_Tgec *p_Tgec = (t_Tgec *) h_Tgec;500uint64_t ethAddr;501uint8_t paddrNum;502503SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);504SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);505506ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);507508if (ethAddr & GROUP_ADDRESS)509/* Multicast address has no effect in PADDR */510RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Multicast address"));511512/* Make sure no PADDR contains this address */513for (paddrNum = 0; paddrNum < TGEC_NUM_OF_PADDRS; paddrNum++)514if (p_Tgec->indAddrRegUsed[paddrNum])515if (p_Tgec->paddr[paddrNum] == ethAddr)516RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);517518/* Find first unused PADDR */519for (paddrNum = 0; paddrNum < TGEC_NUM_OF_PADDRS; paddrNum++)520{521if (!(p_Tgec->indAddrRegUsed[paddrNum]))522{523/* mark this PADDR as used */524p_Tgec->indAddrRegUsed[paddrNum] = TRUE;525/* store address */526p_Tgec->paddr[paddrNum] = ethAddr;527528/* put in hardware */529fman_tgec_add_addr_in_paddr(p_Tgec->p_MemMap, (uint8_t*)(*p_EthAddr)/* , paddrNum */);530p_Tgec->numOfIndAddrInRegs++;531532return E_OK;533}534}535536/* No free PADDR */537RETURN_ERROR(MAJOR, E_FULL, NO_MSG);538}539540/* ......................................................................... */541542static t_Error TgecDelExactMatchMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr)543{544t_Tgec *p_Tgec = (t_Tgec *) h_Tgec;545uint64_t ethAddr;546uint8_t paddrNum;547548SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);549SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);550551ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);552553/* Find used PADDR containing this address */554for (paddrNum = 0; paddrNum < TGEC_NUM_OF_PADDRS; paddrNum++)555{556if ((p_Tgec->indAddrRegUsed[paddrNum]) &&557(p_Tgec->paddr[paddrNum] == ethAddr))558{559/* mark this PADDR as not used */560p_Tgec->indAddrRegUsed[paddrNum] = FALSE;561/* clear in hardware */562fman_tgec_clear_addr_in_paddr(p_Tgec->p_MemMap /*, paddrNum */);563p_Tgec->numOfIndAddrInRegs--;564565return E_OK;566}567}568569RETURN_ERROR(MAJOR, E_NOT_FOUND, NO_MSG);570}571572/* ......................................................................... */573574static t_Error TgecAddHashMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr)575{576t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;577t_EthHashEntry *p_HashEntry;578uint32_t crc;579uint32_t hash;580uint64_t ethAddr;581582SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);583SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);584585ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);586587if (!(ethAddr & GROUP_ADDRESS))588/* Unicast addresses not supported in hash */589RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unicast Address"));590591/* CRC calculation */592crc = GetMacAddrHashCode(ethAddr);593594hash = (crc >> TGEC_HASH_MCAST_SHIFT) & TGEC_HASH_ADR_MSK; /* Take 9 MSB bits */595596/* Create element to be added to the driver hash table */597p_HashEntry = (t_EthHashEntry *)XX_Malloc(sizeof(t_EthHashEntry));598p_HashEntry->addr = ethAddr;599INIT_LIST(&p_HashEntry->node);600601NCSW_LIST_AddToTail(&(p_HashEntry->node), &(p_Tgec->p_MulticastAddrHash->p_Lsts[hash]));602fman_tgec_set_hash_table(p_Tgec->p_MemMap, (hash | TGEC_HASH_MCAST_EN));603604return E_OK;605}606607/* ......................................................................... */608609static t_Error TgecDelHashMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr)610{611t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;612t_EthHashEntry *p_HashEntry = NULL;613t_List *p_Pos;614uint32_t crc;615uint32_t hash;616uint64_t ethAddr;617618SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);619SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);620621ethAddr = ((*(uint64_t *)p_EthAddr) >> 16);622623/* CRC calculation */624crc = GetMacAddrHashCode(ethAddr);625626hash = (crc >> TGEC_HASH_MCAST_SHIFT) & TGEC_HASH_ADR_MSK; /* Take 9 MSB bits */627628NCSW_LIST_FOR_EACH(p_Pos, &(p_Tgec->p_MulticastAddrHash->p_Lsts[hash]))629{630p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos);631if (p_HashEntry->addr == ethAddr)632{633NCSW_LIST_DelAndInit(&p_HashEntry->node);634XX_Free(p_HashEntry);635break;636}637}638if (NCSW_LIST_IsEmpty(&p_Tgec->p_MulticastAddrHash->p_Lsts[hash]))639fman_tgec_set_hash_table(p_Tgec->p_MemMap, (hash & ~TGEC_HASH_MCAST_EN));640641return E_OK;642}643644/* ......................................................................... */645646static t_Error TgecGetId(t_Handle h_Tgec, uint32_t *macId)647{648t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;649650SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);651SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);652653UNUSED(p_Tgec);654UNUSED(macId);655RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("TgecGetId Not Supported"));656}657658/* ......................................................................... */659660static t_Error TgecGetVersion(t_Handle h_Tgec, uint32_t *macVersion)661{662t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;663664SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);665SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);666667*macVersion = fman_tgec_get_revision(p_Tgec->p_MemMap);668669return E_OK;670}671672/* ......................................................................... */673674static t_Error TgecSetExcpetion(t_Handle h_Tgec, e_FmMacExceptions exception, bool enable)675{676t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;677uint32_t bitMask = 0;678679SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);680SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);681682GET_EXCEPTION_FLAG(bitMask, exception);683if (bitMask)684{685if (enable)686p_Tgec->exceptions |= bitMask;687else688p_Tgec->exceptions &= ~bitMask;689}690else691RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));692693if (enable)694fman_tgec_enable_interrupt(p_Tgec->p_MemMap, bitMask);695else696fman_tgec_disable_interrupt(p_Tgec->p_MemMap, bitMask);697698return E_OK;699}700701/* ......................................................................... */702703static uint16_t TgecGetMaxFrameLength(t_Handle h_Tgec)704{705t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;706707SANITY_CHECK_RETURN_VALUE(p_Tgec, E_INVALID_HANDLE, 0);708SANITY_CHECK_RETURN_VALUE(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE, 0);709710return fman_tgec_get_max_frame_len(p_Tgec->p_MemMap);711}712713/* ......................................................................... */714715#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004716static t_Error TgecTxEccWorkaround(t_Tgec *p_Tgec)717{718t_Error err;719720#if defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)721XX_Print("Applying 10G TX ECC workaround (10GMAC-A004) ... ");722#endif /* (DEBUG_ERRORS > 0) */723/* enable and set promiscuous */724fman_tgec_enable(p_Tgec->p_MemMap, TRUE, TRUE);725fman_tgec_set_promiscuous(p_Tgec->p_MemMap, TRUE);726err = Fm10GTxEccWorkaround(p_Tgec->fmMacControllerDriver.h_Fm, p_Tgec->macId);727/* disable */728fman_tgec_set_promiscuous(p_Tgec->p_MemMap, FALSE);729fman_tgec_enable(p_Tgec->p_MemMap, FALSE, FALSE);730fman_tgec_reset_stat(p_Tgec->p_MemMap);731fman_tgec_ack_event(p_Tgec->p_MemMap, 0xffffffff);732#if defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)733if (err)734XX_Print("FAILED!\n");735else736XX_Print("done.\n");737#endif /* (DEBUG_ERRORS > 0) */738739return err;740}741#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */742743/*****************************************************************************/744/* FM Init & Free API */745/*****************************************************************************/746747/* ......................................................................... */748749static t_Error TgecInit(t_Handle h_Tgec)750{751t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;752struct tgec_cfg *p_TgecDriverParam;753t_EnetAddr ethAddr;754t_Error err;755756SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);757SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);758SANITY_CHECK_RETURN_ERROR(p_Tgec->fmMacControllerDriver.h_Fm, E_INVALID_HANDLE);759760FM_GetRevision(p_Tgec->fmMacControllerDriver.h_Fm, &p_Tgec->fmMacControllerDriver.fmRevInfo);761CHECK_INIT_PARAMETERS(p_Tgec, CheckInitParameters);762763p_TgecDriverParam = p_Tgec->p_TgecDriverParam;764765MAKE_ENET_ADDR_FROM_UINT64(p_Tgec->addr, ethAddr);766fman_tgec_set_mac_address(p_Tgec->p_MemMap, (uint8_t *)ethAddr);767768/* interrupts */769#ifdef FM_10G_REM_N_LCL_FLT_EX_10GMAC_ERRATA_SW005770{771if (p_Tgec->fmMacControllerDriver.fmRevInfo.majorRev <=2)772p_Tgec->exceptions &= ~(TGEC_IMASK_REM_FAULT | TGEC_IMASK_LOC_FAULT);773}774#endif /* FM_10G_REM_N_LCL_FLT_EX_10GMAC_ERRATA_SW005 */775776#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004777if (!p_Tgec->p_TgecDriverParam->skip_fman11_workaround &&778((err = TgecTxEccWorkaround(p_Tgec)) != E_OK))779{780FreeInitResources(p_Tgec);781REPORT_ERROR(MINOR, err, ("TgecTxEccWorkaround FAILED"));782}783#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */784785err = fman_tgec_init(p_Tgec->p_MemMap, p_TgecDriverParam, p_Tgec->exceptions);786if (err)787{788FreeInitResources(p_Tgec);789RETURN_ERROR(MAJOR, err, ("This TGEC version does not support the required i/f mode"));790}791792/* Max Frame Length */793err = FmSetMacMaxFrame(p_Tgec->fmMacControllerDriver.h_Fm,794e_FM_MAC_10G,795p_Tgec->fmMacControllerDriver.macId,796p_TgecDriverParam->max_frame_length);797if (err != E_OK)798{799FreeInitResources(p_Tgec);800RETURN_ERROR(MINOR, err, NO_MSG);801}802/* we consider having no IPC a non crasher... */803804#ifdef FM_TX_FIFO_CORRUPTION_ERRATA_10GMAC_A007805if (p_Tgec->fmMacControllerDriver.fmRevInfo.majorRev == 2)806fman_tgec_set_erratum_tx_fifo_corruption_10gmac_a007(p_Tgec->p_MemMap);807#endif /* FM_TX_FIFO_CORRUPTION_ERRATA_10GMAC_A007 */808809p_Tgec->p_MulticastAddrHash = AllocHashTable(HASH_TABLE_SIZE);810if (!p_Tgec->p_MulticastAddrHash)811{812FreeInitResources(p_Tgec);813RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED"));814}815816p_Tgec->p_UnicastAddrHash = AllocHashTable(HASH_TABLE_SIZE);817if (!p_Tgec->p_UnicastAddrHash)818{819FreeInitResources(p_Tgec);820RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED"));821}822823FmRegisterIntr(p_Tgec->fmMacControllerDriver.h_Fm,824e_FM_MOD_10G_MAC,825p_Tgec->macId,826e_FM_INTR_TYPE_ERR,827TgecErrException,828p_Tgec);829if (p_Tgec->mdioIrq != NO_IRQ)830{831XX_SetIntr(p_Tgec->mdioIrq, TgecException, p_Tgec);832XX_EnableIntr(p_Tgec->mdioIrq);833}834835XX_Free(p_TgecDriverParam);836p_Tgec->p_TgecDriverParam = NULL;837838return E_OK;839}840841/* ......................................................................... */842843static t_Error TgecFree(t_Handle h_Tgec)844{845t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;846847SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);848849if (p_Tgec->p_TgecDriverParam)850{851/* Called after config */852XX_Free(p_Tgec->p_TgecDriverParam);853p_Tgec->p_TgecDriverParam = NULL;854}855else856/* Called after init */857FreeInitResources(p_Tgec);858859XX_Free(p_Tgec);860861return E_OK;862}863864/* ......................................................................... */865866static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacControllerDriver)867{868p_FmMacControllerDriver->f_FM_MAC_Init = TgecInit;869p_FmMacControllerDriver->f_FM_MAC_Free = TgecFree;870871p_FmMacControllerDriver->f_FM_MAC_SetStatistics = NULL;872p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback = TgecConfigLoopback;873p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength = TgecConfigMaxFrameLength;874875p_FmMacControllerDriver->f_FM_MAC_ConfigWan = TgecConfigWan;876877p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc = NULL; /* TGEC always works with pad+crc */878p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex = NULL; /* half-duplex is not supported in xgec */879p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck = TgecConfigLengthCheck;880p_FmMacControllerDriver->f_FM_MAC_ConfigException = TgecConfigException;881p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit = NULL;882883#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004884p_FmMacControllerDriver->f_FM_MAC_ConfigSkipFman11Workaround= TgecConfigSkipFman11Workaround;885#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */886887p_FmMacControllerDriver->f_FM_MAC_SetException = TgecSetExcpetion;888889p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp = TgecEnable1588TimeStamp;890p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp = TgecDisable1588TimeStamp;891892p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous = TgecSetPromiscuous;893p_FmMacControllerDriver->f_FM_MAC_AdjustLink = NULL;894p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan = NULL;895p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg = NULL;896897p_FmMacControllerDriver->f_FM_MAC_Enable = TgecEnable;898p_FmMacControllerDriver->f_FM_MAC_Disable = TgecDisable;899p_FmMacControllerDriver->f_FM_MAC_Resume = NULL;900901p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames = TgecTxMacPause;902p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames = TgecSetTxPauseFrames;903p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames = TgecRxIgnoreMacPause;904905p_FmMacControllerDriver->f_FM_MAC_ResetCounters = TgecResetCounters;906p_FmMacControllerDriver->f_FM_MAC_GetStatistics = TgecGetStatistics;907908p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr = TgecModifyMacAddress;909p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr = TgecAddHashMacAddress;910p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr = TgecDelHashMacAddress;911p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr = TgecAddExactMatchMacAddress;912p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr = TgecDelExactMatchMacAddress;913p_FmMacControllerDriver->f_FM_MAC_GetId = TgecGetId;914p_FmMacControllerDriver->f_FM_MAC_GetVersion = TgecGetVersion;915p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength = TgecGetMaxFrameLength;916917p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg = TGEC_MII_WritePhyReg;918p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg = TGEC_MII_ReadPhyReg;919}920921922/*****************************************************************************/923/* Tgec Config Main Entry */924/*****************************************************************************/925926/* ......................................................................... */927928t_Handle TGEC_Config(t_FmMacParams *p_FmMacParam)929{930t_Tgec *p_Tgec;931struct tgec_cfg *p_TgecDriverParam;932uintptr_t baseAddr;933934SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_NULL_POINTER, NULL);935936baseAddr = p_FmMacParam->baseAddr;937/* allocate memory for the UCC GETH data structure. */938p_Tgec = (t_Tgec *)XX_Malloc(sizeof(t_Tgec));939if (!p_Tgec)940{941REPORT_ERROR(MAJOR, E_NO_MEMORY, ("10G MAC driver structure"));942return NULL;943}944memset(p_Tgec, 0, sizeof(t_Tgec));945InitFmMacControllerDriver(&p_Tgec->fmMacControllerDriver);946947/* allocate memory for the 10G MAC driver parameters data structure. */948p_TgecDriverParam = (struct tgec_cfg *) XX_Malloc(sizeof(struct tgec_cfg));949if (!p_TgecDriverParam)950{951REPORT_ERROR(MAJOR, E_NO_MEMORY, ("10G MAC driver parameters"));952XX_Free(p_Tgec);953return NULL;954}955memset(p_TgecDriverParam, 0, sizeof(struct tgec_cfg));956957/* Plant parameter structure pointer */958p_Tgec->p_TgecDriverParam = p_TgecDriverParam;959960fman_tgec_defconfig(p_TgecDriverParam);961962p_Tgec->p_MemMap = (struct tgec_regs *)UINT_TO_PTR(baseAddr);963p_Tgec->p_MiiMemMap = (t_TgecMiiAccessMemMap *)UINT_TO_PTR(baseAddr + TGEC_TO_MII_OFFSET);964p_Tgec->addr = ENET_ADDR_TO_UINT64(p_FmMacParam->addr);965p_Tgec->enetMode = p_FmMacParam->enetMode;966p_Tgec->macId = p_FmMacParam->macId;967p_Tgec->exceptions = DEFAULT_exceptions;968p_Tgec->mdioIrq = p_FmMacParam->mdioIrq;969p_Tgec->f_Exception = p_FmMacParam->f_Exception;970p_Tgec->f_Event = p_FmMacParam->f_Event;971p_Tgec->h_App = p_FmMacParam->h_App;972973return p_Tgec;974}975976977