The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/ncsw/Peripherals/FM/MAC/memac.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 64d70195a11a8cf2619015a87a6a1920


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.