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/dtsec.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-2013 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  @File          dtsec.c
   35 
   36  @Description   FMan dTSEC driver
   37 *//***************************************************************************/
   38 
   39 #include "std_ext.h"
   40 #include "error_ext.h"
   41 #include "string_ext.h"
   42 #include "xx_ext.h"
   43 #include "endian_ext.h"
   44 #include "debug_ext.h"
   45 #include "crc_mac_addr_ext.h"
   46 
   47 #include "fm_common.h"
   48 #include "dtsec.h"
   49 #include "fsl_fman_dtsec.h"
   50 #include "fsl_fman_dtsec_mii_acc.h"
   51 
   52 /*****************************************************************************/
   53 /*                      Internal routines                                    */
   54 /*****************************************************************************/
   55 
   56 static t_Error CheckInitParameters(t_Dtsec *p_Dtsec)
   57 {
   58     if (ENET_SPEED_FROM_MODE(p_Dtsec->enetMode) >= e_ENET_SPEED_10000)
   59         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet 1G MAC driver only supports 1G or lower speeds"));
   60     if (p_Dtsec->macId >= FM_MAX_NUM_OF_1G_MACS)
   61         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("macId can not be greater than the number of 1G MACs"));
   62     if (p_Dtsec->addr == 0)
   63         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet MAC Must have a valid MAC Address"));
   64     if ((ENET_SPEED_FROM_MODE(p_Dtsec->enetMode) >= e_ENET_SPEED_1000) &&
   65         p_Dtsec->p_DtsecDriverParam->halfdup_on)
   66         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet MAC 1G can't work in half duplex"));
   67     if (p_Dtsec->p_DtsecDriverParam->halfdup_on && (p_Dtsec->p_DtsecDriverParam)->loopback)
   68         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("LoopBack is not supported in halfDuplex mode"));
   69 #ifdef FM_RX_PREAM_4_ERRATA_DTSEC_A001
   70     if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev <= 6) /* fixed for rev3 */
   71         if (p_Dtsec->p_DtsecDriverParam->rx_preamble)
   72             RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("preambleRxEn"));
   73 #endif /* FM_RX_PREAM_4_ERRATA_DTSEC_A001 */
   74     if (((p_Dtsec->p_DtsecDriverParam)->tx_preamble || (p_Dtsec->p_DtsecDriverParam)->rx_preamble) &&( (p_Dtsec->p_DtsecDriverParam)->preamble_len != 0x7))
   75         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Preamble length should be 0x7 bytes"));
   76     if ((p_Dtsec->p_DtsecDriverParam)->halfdup_on &&
   77        (p_Dtsec->p_DtsecDriverParam->tx_time_stamp_en || p_Dtsec->p_DtsecDriverParam->rx_time_stamp_en))
   78         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dTSEC in half duplex mode has to be with 1588 timeStamping diable"));
   79     if ((p_Dtsec->p_DtsecDriverParam)->rx_flow && (p_Dtsec->p_DtsecDriverParam)->rx_ctrl_acc )
   80         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Receive control frame are not passed to the system memory so it can not be accept "));
   81     if ((p_Dtsec->p_DtsecDriverParam)->rx_prepend  > MAX_PACKET_ALIGNMENT)
   82         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("packetAlignmentPadding can't be greater than %d ",MAX_PACKET_ALIGNMENT ));
   83     if (((p_Dtsec->p_DtsecDriverParam)->non_back_to_back_ipg1  > MAX_INTER_PACKET_GAP) ||
   84         ((p_Dtsec->p_DtsecDriverParam)->non_back_to_back_ipg2 > MAX_INTER_PACKET_GAP) ||
   85         ((p_Dtsec->p_DtsecDriverParam)->back_to_back_ipg > MAX_INTER_PACKET_GAP))
   86         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inter packet gap can't be greater than %d ",MAX_INTER_PACKET_GAP ));
   87     if ((p_Dtsec->p_DtsecDriverParam)->halfdup_alt_backoff_val > MAX_INTER_PALTERNATE_BEB)
   88         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("alternateBackoffVal can't be greater than %d ",MAX_INTER_PALTERNATE_BEB ));
   89     if ((p_Dtsec->p_DtsecDriverParam)->halfdup_retransmit > MAX_RETRANSMISSION)
   90         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("maxRetransmission can't be greater than %d ",MAX_RETRANSMISSION ));
   91     if ((p_Dtsec->p_DtsecDriverParam)->halfdup_coll_window > MAX_COLLISION_WINDOW)
   92         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("collisionWindow can't be greater than %d ",MAX_COLLISION_WINDOW ));
   93 
   94     /*  If Auto negotiation process is disabled, need to */
   95     /*  Set up the PHY using the MII Management Interface */
   96     if (p_Dtsec->p_DtsecDriverParam->tbipa > MAX_PHYS)
   97         RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, ("PHY address (should be 0-%d)", MAX_PHYS));
   98     if (!p_Dtsec->f_Exception)
   99         RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("uninitialized f_Exception"));
  100     if (!p_Dtsec->f_Event)
  101         RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("uninitialized f_Event"));
  102 
  103 #ifdef FM_LEN_CHECK_ERRATA_FMAN_SW002
  104     if (p_Dtsec->p_DtsecDriverParam->rx_len_check)
  105        RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("LengthCheck!"));
  106 #endif /* FM_LEN_CHECK_ERRATA_FMAN_SW002 */
  107 
  108     return E_OK;
  109 }
  110 
  111 /* ......................................................................... */
  112 
  113 static uint32_t GetMacAddrHashCode(uint64_t ethAddr)
  114 {
  115     uint32_t crc;
  116 
  117     /* CRC calculation */
  118     GET_MAC_ADDR_CRC(ethAddr, crc);
  119 
  120     crc = GetMirror32(crc);
  121 
  122     return crc;
  123 }
  124 
  125 /* ......................................................................... */
  126 
  127 static void UpdateStatistics(t_Dtsec *p_Dtsec)
  128 {
  129     uint32_t car1, car2;
  130 
  131     fman_dtsec_get_clear_carry_regs(p_Dtsec->p_MemMap, &car1, &car2);
  132 
  133     if (car1)
  134     {
  135         if (car1 & CAR1_TR64)
  136             p_Dtsec->internalStatistics.tr64 += VAL22BIT;
  137         if (car1 & CAR1_TR127)
  138             p_Dtsec->internalStatistics.tr127 += VAL22BIT;
  139         if (car1 & CAR1_TR255)
  140             p_Dtsec->internalStatistics.tr255 += VAL22BIT;
  141         if (car1 & CAR1_TR511)
  142             p_Dtsec->internalStatistics.tr511 += VAL22BIT;
  143         if (car1 & CAR1_TRK1)
  144             p_Dtsec->internalStatistics.tr1k += VAL22BIT;
  145         if (car1 & CAR1_TRMAX)
  146             p_Dtsec->internalStatistics.trmax += VAL22BIT;
  147         if (car1 & CAR1_TRMGV)
  148             p_Dtsec->internalStatistics.trmgv += VAL22BIT;
  149         if (car1 & CAR1_RBYT)
  150             p_Dtsec->internalStatistics.rbyt += (uint64_t)VAL32BIT;
  151         if (car1 & CAR1_RPKT)
  152             p_Dtsec->internalStatistics.rpkt += VAL22BIT;
  153         if (car1 & CAR1_RMCA)
  154             p_Dtsec->internalStatistics.rmca += VAL22BIT;
  155         if (car1 & CAR1_RBCA)
  156             p_Dtsec->internalStatistics.rbca += VAL22BIT;
  157         if (car1 & CAR1_RXPF)
  158             p_Dtsec->internalStatistics.rxpf += VAL16BIT;
  159         if (car1 & CAR1_RALN)
  160             p_Dtsec->internalStatistics.raln += VAL16BIT;
  161         if (car1 & CAR1_RFLR)
  162             p_Dtsec->internalStatistics.rflr += VAL16BIT;
  163         if (car1 & CAR1_RCDE)
  164             p_Dtsec->internalStatistics.rcde += VAL16BIT;
  165         if (car1 & CAR1_RCSE)
  166             p_Dtsec->internalStatistics.rcse += VAL16BIT;
  167         if (car1 & CAR1_RUND)
  168             p_Dtsec->internalStatistics.rund += VAL16BIT;
  169         if (car1 & CAR1_ROVR)
  170             p_Dtsec->internalStatistics.rovr += VAL16BIT;
  171         if (car1 & CAR1_RFRG)
  172             p_Dtsec->internalStatistics.rfrg += VAL16BIT;
  173         if (car1 & CAR1_RJBR)
  174             p_Dtsec->internalStatistics.rjbr += VAL16BIT;
  175         if (car1 & CAR1_RDRP)
  176             p_Dtsec->internalStatistics.rdrp += VAL16BIT;
  177     }
  178     if (car2)
  179     {
  180         if (car2  & CAR2_TFCS)
  181             p_Dtsec->internalStatistics.tfcs += VAL12BIT;
  182         if (car2  & CAR2_TBYT)
  183             p_Dtsec->internalStatistics.tbyt += (uint64_t)VAL32BIT;
  184         if (car2  & CAR2_TPKT)
  185             p_Dtsec->internalStatistics.tpkt += VAL22BIT;
  186         if (car2  & CAR2_TMCA)
  187             p_Dtsec->internalStatistics.tmca += VAL22BIT;
  188         if (car2  & CAR2_TBCA)
  189             p_Dtsec->internalStatistics.tbca += VAL22BIT;
  190         if (car2  & CAR2_TXPF)
  191             p_Dtsec->internalStatistics.txpf += VAL16BIT;
  192         if (car2  & CAR2_TDRP)
  193             p_Dtsec->internalStatistics.tdrp += VAL16BIT;
  194     }
  195 }
  196 
  197 /* .............................................................................. */
  198 
  199 static uint16_t DtsecGetMaxFrameLength(t_Handle h_Dtsec)
  200 {
  201     t_Dtsec     *p_Dtsec = (t_Dtsec *)h_Dtsec;
  202 
  203     SANITY_CHECK_RETURN_VALUE(p_Dtsec, E_INVALID_HANDLE, 0);
  204     SANITY_CHECK_RETURN_VALUE(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE, 0);
  205 
  206     return fman_dtsec_get_max_frame_len(p_Dtsec->p_MemMap);
  207 }
  208 
  209 /* .............................................................................. */
  210 
  211 static void DtsecIsr(t_Handle h_Dtsec)
  212 {
  213     t_Dtsec             *p_Dtsec = (t_Dtsec *)h_Dtsec;
  214     uint32_t            event;
  215     struct dtsec_regs   *p_DtsecMemMap = p_Dtsec->p_MemMap;
  216 
  217     /* do not handle MDIO events */
  218     event = fman_dtsec_get_event(p_DtsecMemMap, (uint32_t)(~(DTSEC_IMASK_MMRDEN | DTSEC_IMASK_MMWREN)));
  219 
  220     event &= fman_dtsec_get_interrupt_mask(p_DtsecMemMap);
  221 
  222     fman_dtsec_ack_event(p_DtsecMemMap, event);
  223 
  224     if (event & DTSEC_IMASK_BREN)
  225         p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_BAB_RX);
  226     if (event & DTSEC_IMASK_RXCEN)
  227         p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_RX_CTL);
  228     if (event & DTSEC_IMASK_MSROEN)
  229         UpdateStatistics(p_Dtsec);
  230     if (event & DTSEC_IMASK_GTSCEN)
  231         p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET);
  232     if (event & DTSEC_IMASK_BTEN)
  233         p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_BAB_TX);
  234     if (event & DTSEC_IMASK_TXCEN)
  235         p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_CTL);
  236     if (event & DTSEC_IMASK_TXEEN)
  237         p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_ERR);
  238     if (event & DTSEC_IMASK_LCEN)
  239         p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_LATE_COL);
  240     if (event & DTSEC_IMASK_CRLEN)
  241         p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_COL_RET_LMT);
  242     if (event & DTSEC_IMASK_XFUNEN)
  243     {
  244 #ifdef FM_TX_LOCKUP_ERRATA_DTSEC6
  245         if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
  246         {
  247             uint32_t  tpkt1, tmpReg1, tpkt2, tmpReg2, i;
  248             /* a. Write 0x00E0_0C00 to DTSEC_ID */
  249             /* This is a read only regidter */
  250 
  251             /* b. Read and save the value of TPKT */
  252             tpkt1 = GET_UINT32(p_DtsecMemMap->tpkt);
  253 
  254             /* c. Read the register at dTSEC address offset 0x32C */
  255             tmpReg1 =  GET_UINT32(*(uint32_t*)((uint8_t*)p_DtsecMemMap + 0x32c));
  256 
  257             /* d. Compare bits [9:15] to bits [25:31] of the register at address offset 0x32C. */
  258             if ((tmpReg1 & 0x007F0000) != (tmpReg1 & 0x0000007F))
  259             {
  260                 /* If they are not equal, save the value of this register and wait for at least
  261                  * MAXFRM*16 ns */
  262                 XX_UDelay((uint32_t)(MIN(DtsecGetMaxFrameLength(p_Dtsec)*16/1000, 1)));
  263             }
  264 
  265             /* e. Read and save TPKT again and read the register at dTSEC address offset
  266                 0x32C again*/
  267             tpkt2 = GET_UINT32(p_DtsecMemMap->tpkt);
  268             tmpReg2 = GET_UINT32(*(uint32_t*)((uint8_t*)p_DtsecMemMap + 0x32c));
  269 
  270             /* f. Compare the value of TPKT saved in step b to value read in step e. Also
  271                 compare bits [9:15] of the register at offset 0x32C saved in step d to the value
  272                 of bits [9:15] saved in step e. If the two registers values are unchanged, then
  273                 the transmit portion of the dTSEC controller is locked up and the user should
  274                 proceed to the recover sequence. */
  275             if ((tpkt1 == tpkt2) && ((tmpReg1 & 0x007F0000) == (tmpReg2 & 0x007F0000)))
  276             {
  277                 /* recover sequence */
  278 
  279                 /* a.Write a 1 to RCTRL[GRS]*/
  280 
  281                 WRITE_UINT32(p_DtsecMemMap->rctrl, GET_UINT32(p_DtsecMemMap->rctrl) | RCTRL_GRS);
  282 
  283                 /* b.Wait until IEVENT[GRSC]=1, or at least 100 us has elapsed. */
  284                 for (i = 0 ; i < 100 ; i++ )
  285                 {
  286                     if (GET_UINT32(p_DtsecMemMap->ievent) & DTSEC_IMASK_GRSCEN)
  287                         break;
  288                     XX_UDelay(1);
  289                 }
  290                 if (GET_UINT32(p_DtsecMemMap->ievent) & DTSEC_IMASK_GRSCEN)
  291                     WRITE_UINT32(p_DtsecMemMap->ievent, DTSEC_IMASK_GRSCEN);
  292                 else
  293                     DBG(INFO,("Rx lockup due to dTSEC Tx lockup"));
  294 
  295                 /* c.Write a 1 to bit n of FM_RSTC (offset 0x0CC of FPM)*/
  296                 FmResetMac(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MAC_1G, p_Dtsec->fmMacControllerDriver.macId);
  297 
  298                 /* d.Wait 4 Tx clocks (32 ns) */
  299                 XX_UDelay(1);
  300 
  301                 /* e.Write a 0 to bit n of FM_RSTC. */
  302                 /* cleared by FMAN */
  303             }
  304         }
  305 #endif /* FM_TX_LOCKUP_ERRATA_DTSEC6 */
  306 
  307         p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_FIFO_UNDRN);
  308     }
  309     if (event & DTSEC_IMASK_MAGEN)
  310         p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_MAG_PCKT);
  311     if (event & DTSEC_IMASK_GRSCEN)
  312         p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET);
  313     if (event & DTSEC_IMASK_TDPEEN)
  314         p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_DATA_ERR);
  315     if (event & DTSEC_IMASK_RDPEEN)
  316         p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_RX_DATA_ERR);
  317 
  318     /*  - masked interrupts */
  319     ASSERT_COND(!(event & DTSEC_IMASK_ABRTEN));
  320     ASSERT_COND(!(event & DTSEC_IMASK_IFERREN));
  321 }
  322 
  323 static void DtsecMdioIsr(t_Handle h_Dtsec)
  324 {
  325     t_Dtsec             *p_Dtsec = (t_Dtsec *)h_Dtsec;
  326     uint32_t            event;
  327     struct dtsec_regs   *p_DtsecMemMap = p_Dtsec->p_MemMap;
  328 
  329     event = GET_UINT32(p_DtsecMemMap->ievent);
  330     /* handle only MDIO events */
  331     event &= (DTSEC_IMASK_MMRDEN | DTSEC_IMASK_MMWREN);
  332     if (event)
  333     {
  334         event &= GET_UINT32(p_DtsecMemMap->imask);
  335 
  336         WRITE_UINT32(p_DtsecMemMap->ievent, event);
  337 
  338         if (event & DTSEC_IMASK_MMRDEN)
  339             p_Dtsec->f_Event(p_Dtsec->h_App, e_FM_MAC_EX_1G_MII_MNG_RD_COMPLET);
  340         if (event & DTSEC_IMASK_MMWREN)
  341             p_Dtsec->f_Event(p_Dtsec->h_App, e_FM_MAC_EX_1G_MII_MNG_WR_COMPLET);
  342     }
  343 }
  344 
  345 static void Dtsec1588Isr(t_Handle h_Dtsec)
  346 {
  347     t_Dtsec             *p_Dtsec = (t_Dtsec *)h_Dtsec;
  348     uint32_t            event;
  349     struct dtsec_regs   *p_DtsecMemMap = p_Dtsec->p_MemMap;
  350 
  351     if (p_Dtsec->ptpTsuEnabled)
  352     {
  353         event = fman_dtsec_check_and_clear_tmr_event(p_DtsecMemMap);
  354 
  355         if (event)
  356         {
  357             ASSERT_COND(event & TMR_PEVENT_TSRE);
  358             p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_1588_TS_RX_ERR);
  359         }
  360     }
  361 }
  362 
  363 /* ........................................................................... */
  364 
  365 static void FreeInitResources(t_Dtsec *p_Dtsec)
  366 {
  367     if (p_Dtsec->mdioIrq != NO_IRQ)
  368     {
  369         XX_DisableIntr(p_Dtsec->mdioIrq);
  370         XX_FreeIntr(p_Dtsec->mdioIrq);
  371     }
  372     FmUnregisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Dtsec->macId, e_FM_INTR_TYPE_ERR);
  373     FmUnregisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Dtsec->macId, e_FM_INTR_TYPE_NORMAL);
  374 
  375     /* release the driver's group hash table */
  376     FreeHashTable(p_Dtsec->p_MulticastAddrHash);
  377     p_Dtsec->p_MulticastAddrHash =   NULL;
  378 
  379     /* release the driver's individual hash table */
  380     FreeHashTable(p_Dtsec->p_UnicastAddrHash);
  381     p_Dtsec->p_UnicastAddrHash =     NULL;
  382 }
  383 
  384 /* ........................................................................... */
  385 
  386 static t_Error GracefulStop(t_Dtsec *p_Dtsec, e_CommMode mode)
  387 {
  388     struct dtsec_regs *p_MemMap;
  389 
  390     ASSERT_COND(p_Dtsec);
  391 
  392     p_MemMap = p_Dtsec->p_MemMap;
  393     ASSERT_COND(p_MemMap);
  394 
  395     /* Assert the graceful transmit stop bit */
  396     if (mode & e_COMM_MODE_RX)
  397     {
  398         fman_dtsec_stop_rx(p_MemMap);
  399 
  400 #ifdef FM_GRS_ERRATA_DTSEC_A002
  401         if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
  402             XX_UDelay(100);
  403 #else  /* FM_GRS_ERRATA_DTSEC_A002 */
  404 #ifdef FM_GTS_AFTER_DROPPED_FRAME_ERRATA_DTSEC_A004839
  405         XX_UDelay(10);
  406 #endif /* FM_GTS_AFTER_DROPPED_FRAME_ERRATA_DTSEC_A004839 */
  407 #endif /* FM_GRS_ERRATA_DTSEC_A002 */
  408     }
  409 
  410     if (mode & e_COMM_MODE_TX)
  411 #if defined(FM_GTS_ERRATA_DTSEC_A004) || defined(FM_GTS_AFTER_MAC_ABORTED_FRAME_ERRATA_DTSEC_A0012)
  412     if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
  413         DBG(INFO, ("GTS not supported due to DTSEC_A004 errata."));
  414 #else  /* not defined(FM_GTS_ERRATA_DTSEC_A004) ||... */
  415 #ifdef FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014
  416         DBG(INFO, ("GTS not supported due to DTSEC_A0014 errata."));
  417 #else  /* FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014 */
  418         fman_dtsec_stop_tx(p_MemMap);
  419 #endif /* FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014 */
  420 #endif /* defined(FM_GTS_ERRATA_DTSEC_A004) ||...  */
  421 
  422     return E_OK;
  423 }
  424 
  425 /* .............................................................................. */
  426 
  427 static t_Error GracefulRestart(t_Dtsec *p_Dtsec, e_CommMode mode)
  428 {
  429     struct dtsec_regs *p_MemMap;
  430 
  431     ASSERT_COND(p_Dtsec);
  432     p_MemMap = p_Dtsec->p_MemMap;
  433     ASSERT_COND(p_MemMap);
  434 
  435     /* clear the graceful receive stop bit */
  436     if (mode & e_COMM_MODE_TX)
  437         fman_dtsec_start_tx(p_MemMap);
  438 
  439     if (mode & e_COMM_MODE_RX)
  440         fman_dtsec_start_rx(p_MemMap);
  441 
  442     return E_OK;
  443 }
  444 
  445 
  446 /*****************************************************************************/
  447 /*                      dTSEC Configs modification functions                 */
  448 /*****************************************************************************/
  449 
  450 /* .............................................................................. */
  451 
  452 static t_Error DtsecConfigLoopback(t_Handle h_Dtsec, bool newVal)
  453 {
  454 
  455     t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
  456 
  457     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
  458     SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
  459 
  460     p_Dtsec->p_DtsecDriverParam->loopback = newVal;
  461 
  462     return E_OK;
  463 }
  464 
  465 /* .............................................................................. */
  466 
  467 static t_Error DtsecConfigMaxFrameLength(t_Handle h_Dtsec, uint16_t newVal)
  468 {
  469     t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
  470 
  471     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
  472     SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
  473 
  474     p_Dtsec->p_DtsecDriverParam->maximum_frame = newVal;
  475 
  476     return E_OK;
  477 }
  478 
  479 /* .............................................................................. */
  480 
  481 static t_Error DtsecConfigPadAndCrc(t_Handle h_Dtsec, bool newVal)
  482 {
  483     t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
  484 
  485     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
  486     SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
  487 
  488     p_Dtsec->p_DtsecDriverParam->tx_pad_crc = newVal;
  489 
  490     return E_OK;
  491 }
  492 
  493 /* .............................................................................. */
  494 
  495 static t_Error DtsecConfigHalfDuplex(t_Handle h_Dtsec, bool newVal)
  496 {
  497     t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
  498 
  499     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
  500     SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
  501 
  502     p_Dtsec->p_DtsecDriverParam->halfdup_on = newVal;
  503 
  504     return E_OK;
  505 }
  506 
  507 /* .............................................................................. */
  508 
  509 static t_Error DtsecConfigTbiPhyAddr(t_Handle h_Dtsec, uint8_t newVal)
  510 {
  511     t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
  512 
  513     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
  514     SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
  515 
  516     p_Dtsec->p_DtsecDriverParam->tbi_phy_addr = newVal;
  517 
  518     return E_OK;
  519 }
  520 
  521 /* .............................................................................. */
  522 
  523 static t_Error DtsecConfigLengthCheck(t_Handle h_Dtsec, bool newVal)
  524 {
  525     t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
  526 
  527     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
  528     SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
  529 
  530     p_Dtsec->p_DtsecDriverParam->rx_len_check = newVal;
  531 
  532     return E_OK;
  533 }
  534 
  535 /* .............................................................................. */
  536 
  537 static t_Error DtsecConfigException(t_Handle h_Dtsec, e_FmMacExceptions exception, bool enable)
  538 {
  539     t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
  540     uint32_t    bitMask = 0;
  541 
  542     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
  543     SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
  544 
  545     if (exception != e_FM_MAC_EX_1G_1588_TS_RX_ERR)
  546     {
  547         GET_EXCEPTION_FLAG(bitMask, exception);
  548         if (bitMask)
  549         {
  550             if (enable)
  551                 p_Dtsec->exceptions |= bitMask;
  552             else
  553                 p_Dtsec->exceptions &= ~bitMask;
  554         }
  555         else
  556             RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
  557     }
  558     else
  559     {
  560         if (!p_Dtsec->ptpTsuEnabled)
  561             RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exception valid for 1588 only"));
  562 
  563         if (enable)
  564             p_Dtsec->enTsuErrExeption = TRUE;
  565         else
  566             p_Dtsec->enTsuErrExeption = FALSE;
  567     }
  568 
  569     return E_OK;
  570 }
  571 
  572 
  573 /*****************************************************************************/
  574 /*                      dTSEC Run Time API functions                         */
  575 /*****************************************************************************/
  576 
  577 /* .............................................................................. */
  578 
  579 static t_Error DtsecEnable(t_Handle h_Dtsec,  e_CommMode mode)
  580 {
  581     t_Dtsec     *p_Dtsec = (t_Dtsec *)h_Dtsec;
  582 
  583     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
  584     SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
  585 
  586     fman_dtsec_enable(p_Dtsec->p_MemMap,
  587                  (bool)!!(mode & e_COMM_MODE_RX),
  588                  (bool)!!(mode & e_COMM_MODE_TX));
  589 
  590     GracefulRestart(p_Dtsec, mode);
  591 
  592     return E_OK;
  593 }
  594 
  595 /* .............................................................................. */
  596 
  597 static t_Error DtsecDisable (t_Handle h_Dtsec, e_CommMode mode)
  598 {
  599     t_Dtsec     *p_Dtsec = (t_Dtsec *)h_Dtsec;
  600 
  601     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
  602     SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
  603 
  604     GracefulStop(p_Dtsec, mode);
  605 
  606     fman_dtsec_disable(p_Dtsec->p_MemMap,
  607                   (bool)!!(mode & e_COMM_MODE_RX),
  608                   (bool)!!(mode & e_COMM_MODE_TX));
  609 
  610     return E_OK;
  611 }
  612 
  613 /* .............................................................................. */
  614 
  615 static t_Error DtsecSetTxPauseFrames(t_Handle h_Dtsec,
  616                                      uint8_t  priority,
  617                                      uint16_t pauseTime,
  618                                      uint16_t threshTime)
  619 {
  620     t_Dtsec     *p_Dtsec = (t_Dtsec *)h_Dtsec;
  621 
  622     UNUSED(priority);UNUSED(threshTime);
  623 
  624     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_STATE);
  625     SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
  626 
  627 #ifdef FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003
  628     if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
  629         if (0 < pauseTime && pauseTime <= 320)
  630             RETURN_ERROR(MINOR, E_INVALID_VALUE,
  631                      ("This pause-time value of %d is illegal due to errata dTSEC-A003!"
  632                       " value should be greater than 320."));
  633 #endif /* FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003 */
  634 
  635     fman_dtsec_set_tx_pause_frames(p_Dtsec->p_MemMap, pauseTime);
  636     return E_OK;
  637 }
  638 
  639 /* .............................................................................. */
  640 /* backward compatibility. will be removed in the future. */
  641 static t_Error DtsecTxMacPause(t_Handle h_Dtsec, uint16_t pauseTime)
  642 {
  643     return DtsecSetTxPauseFrames(h_Dtsec, 0, pauseTime, 0);
  644 }
  645 
  646 /* .............................................................................. */
  647 
  648 static t_Error DtsecRxIgnoreMacPause(t_Handle h_Dtsec, bool en)
  649 {
  650     t_Dtsec         *p_Dtsec = (t_Dtsec *)h_Dtsec;
  651     bool            accept_pause = !en;
  652 
  653     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_STATE);
  654     SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
  655 
  656     fman_dtsec_handle_rx_pause(p_Dtsec->p_MemMap, accept_pause);
  657 
  658     return E_OK;
  659 }
  660 
  661 /* .............................................................................. */
  662 
  663 static t_Error DtsecEnable1588TimeStamp(t_Handle h_Dtsec)
  664 {
  665     t_Dtsec     *p_Dtsec = (t_Dtsec *)h_Dtsec;
  666 
  667     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
  668     SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
  669 
  670     p_Dtsec->ptpTsuEnabled = TRUE;
  671     fman_dtsec_set_ts(p_Dtsec->p_MemMap, TRUE);
  672 
  673     return E_OK;
  674 }
  675 
  676 /* .............................................................................. */
  677 
  678 static t_Error DtsecDisable1588TimeStamp(t_Handle h_Dtsec)
  679 {
  680     t_Dtsec     *p_Dtsec = (t_Dtsec *)h_Dtsec;
  681 
  682     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
  683     SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
  684 
  685     p_Dtsec->ptpTsuEnabled = FALSE;
  686     fman_dtsec_set_ts(p_Dtsec->p_MemMap, FALSE);
  687 
  688     return E_OK;
  689 }
  690 
  691 /* .............................................................................. */
  692 
  693 static t_Error DtsecGetStatistics(t_Handle h_Dtsec, t_FmMacStatistics *p_Statistics)
  694 {
  695     t_Dtsec             *p_Dtsec = (t_Dtsec *)h_Dtsec;
  696     struct dtsec_regs   *p_DtsecMemMap;
  697 
  698     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
  699     SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
  700     SANITY_CHECK_RETURN_ERROR(p_Statistics, E_NULL_POINTER);
  701 
  702     p_DtsecMemMap = p_Dtsec->p_MemMap;
  703 
  704     if (p_Dtsec->statisticsLevel == e_FM_MAC_NONE_STATISTICS)
  705         RETURN_ERROR(MINOR, E_INVALID_STATE, ("Statistics disabled"));
  706 
  707     memset(p_Statistics, 0xff, sizeof(t_FmMacStatistics));
  708 
  709     if (p_Dtsec->statisticsLevel == e_FM_MAC_FULL_STATISTICS)
  710     {
  711         p_Statistics->eStatPkts64 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR64)
  712                 + p_Dtsec->internalStatistics.tr64;
  713         p_Statistics->eStatPkts65to127 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR127)
  714                 + p_Dtsec->internalStatistics.tr127;
  715         p_Statistics->eStatPkts128to255 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR255)
  716                 + p_Dtsec->internalStatistics.tr255;
  717         p_Statistics->eStatPkts256to511 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR511)
  718                 + p_Dtsec->internalStatistics.tr511;
  719         p_Statistics->eStatPkts512to1023 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR1K)
  720                 + p_Dtsec->internalStatistics.tr1k;
  721         p_Statistics->eStatPkts1024to1518 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TRMAX)
  722                 + p_Dtsec->internalStatistics.trmax;
  723         p_Statistics->eStatPkts1519to1522 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TRMGV)
  724                 + p_Dtsec->internalStatistics.trmgv;
  725 
  726         /* MIB II */
  727         p_Statistics->ifInOctets = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RBYT)
  728                 + p_Dtsec->internalStatistics.rbyt;
  729         p_Statistics->ifInPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RPKT)
  730                 + p_Dtsec->internalStatistics.rpkt;
  731         p_Statistics->ifInUcastPkts = 0;
  732         p_Statistics->ifInMcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RMCA)
  733                 + p_Dtsec->internalStatistics.rmca;
  734         p_Statistics->ifInBcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RBCA)
  735                 + p_Dtsec->internalStatistics.rbca;
  736         p_Statistics->ifOutOctets = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TBYT)
  737                 + p_Dtsec->internalStatistics.tbyt;
  738         p_Statistics->ifOutPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TPKT)
  739                 + p_Dtsec->internalStatistics.tpkt;
  740         p_Statistics->ifOutUcastPkts = 0;
  741         p_Statistics->ifOutMcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TMCA)
  742                 + p_Dtsec->internalStatistics.tmca;
  743         p_Statistics->ifOutBcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TBCA)
  744                 + p_Dtsec->internalStatistics.tbca;
  745     }
  746 
  747     p_Statistics->eStatFragments = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RFRG)
  748             + p_Dtsec->internalStatistics.rfrg;
  749     p_Statistics->eStatJabbers = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RJBR)
  750             + p_Dtsec->internalStatistics.rjbr;
  751     p_Statistics->eStatsDropEvents = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RDRP)
  752             + p_Dtsec->internalStatistics.rdrp;
  753     p_Statistics->eStatCRCAlignErrors = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RALN)
  754             + p_Dtsec->internalStatistics.raln;
  755     p_Statistics->eStatUndersizePkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RUND)
  756             + p_Dtsec->internalStatistics.rund;
  757     p_Statistics->eStatOversizePkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_ROVR)
  758             + p_Dtsec->internalStatistics.rovr;
  759     p_Statistics->reStatPause = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RXPF)
  760             + p_Dtsec->internalStatistics.rxpf;
  761     p_Statistics->teStatPause = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TXPF)
  762             + p_Dtsec->internalStatistics.txpf;
  763     p_Statistics->ifInDiscards = p_Statistics->eStatsDropEvents;
  764     p_Statistics->ifInErrors = p_Statistics->eStatsDropEvents + p_Statistics->eStatCRCAlignErrors
  765             + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_RFLR) + p_Dtsec->internalStatistics.rflr
  766             + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_RCDE) + p_Dtsec->internalStatistics.rcde
  767             + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_RCSE) + p_Dtsec->internalStatistics.rcse;
  768 
  769     p_Statistics->ifOutDiscards = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TDRP)
  770             + p_Dtsec->internalStatistics.tdrp;
  771     p_Statistics->ifOutErrors = p_Statistics->ifOutDiscards                                           /**< Number of frames transmitted with error: */
  772             + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_TFCS)
  773             + p_Dtsec->internalStatistics.tfcs;
  774 
  775     return E_OK;
  776 }
  777 
  778 /* .............................................................................. */
  779 
  780 static t_Error DtsecModifyMacAddress (t_Handle h_Dtsec, t_EnetAddr *p_EnetAddr)
  781 {
  782     t_Dtsec     *p_Dtsec = (t_Dtsec *)h_Dtsec;
  783 
  784     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
  785     SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
  786 
  787     /* Initialize MAC Station Address registers (1 & 2)    */
  788     /* Station address have to be swapped (big endian to little endian */
  789     p_Dtsec->addr = ENET_ADDR_TO_UINT64(*p_EnetAddr);
  790     fman_dtsec_set_mac_address(p_Dtsec->p_MemMap, (uint8_t *)(*p_EnetAddr));
  791 
  792     return E_OK;
  793 }
  794 
  795 /* .............................................................................. */
  796 
  797 static t_Error DtsecResetCounters (t_Handle h_Dtsec)
  798 {
  799     t_Dtsec     *p_Dtsec = (t_Dtsec *)h_Dtsec;
  800 
  801     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
  802     SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
  803 
  804     /* clear HW counters */
  805     fman_dtsec_reset_stat(p_Dtsec->p_MemMap);
  806 
  807     /* clear SW counters holding carries */
  808     memset(&p_Dtsec->internalStatistics, 0, sizeof(t_InternalStatistics));
  809 
  810     return E_OK;
  811 }
  812 
  813 /* .............................................................................. */
  814 
  815 static t_Error DtsecAddExactMatchMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
  816 {
  817     t_Dtsec   *p_Dtsec = (t_Dtsec *) h_Dtsec;
  818     uint64_t  ethAddr;
  819     uint8_t   paddrNum;
  820 
  821     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
  822     SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
  823 
  824     ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
  825 
  826     if (ethAddr & GROUP_ADDRESS)
  827         /* Multicast address has no effect in PADDR */
  828         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Multicast address"));
  829 
  830     /* Make sure no PADDR contains this address */
  831     for (paddrNum = 0; paddrNum < DTSEC_NUM_OF_PADDRS; paddrNum++)
  832         if (p_Dtsec->indAddrRegUsed[paddrNum])
  833             if (p_Dtsec->paddr[paddrNum] == ethAddr)
  834                 RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
  835 
  836     /* Find first unused PADDR */
  837     for (paddrNum = 0; paddrNum < DTSEC_NUM_OF_PADDRS; paddrNum++)
  838         if (!(p_Dtsec->indAddrRegUsed[paddrNum]))
  839         {
  840             /* mark this PADDR as used */
  841             p_Dtsec->indAddrRegUsed[paddrNum] = TRUE;
  842             /* store address */
  843             p_Dtsec->paddr[paddrNum] = ethAddr;
  844 
  845             /* put in hardware */
  846             fman_dtsec_add_addr_in_paddr(p_Dtsec->p_MemMap, (uint64_t)PTR_TO_UINT(&ethAddr), paddrNum);
  847             p_Dtsec->numOfIndAddrInRegs++;
  848 
  849             return E_OK;
  850         }
  851 
  852     /* No free PADDR */
  853     RETURN_ERROR(MAJOR, E_FULL, NO_MSG);
  854 }
  855 
  856 /* .............................................................................. */
  857 
  858 static t_Error DtsecDelExactMatchMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
  859 {
  860     t_Dtsec   *p_Dtsec = (t_Dtsec *) h_Dtsec;
  861     uint64_t  ethAddr;
  862     uint8_t   paddrNum;
  863 
  864     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
  865     SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
  866 
  867     ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
  868 
  869     /* Find used PADDR containing this address */
  870     for (paddrNum = 0; paddrNum < DTSEC_NUM_OF_PADDRS; paddrNum++)
  871     {
  872         if ((p_Dtsec->indAddrRegUsed[paddrNum]) &&
  873             (p_Dtsec->paddr[paddrNum] == ethAddr))
  874         {
  875             /* mark this PADDR as not used */
  876             p_Dtsec->indAddrRegUsed[paddrNum] = FALSE;
  877             /* clear in hardware */
  878             fman_dtsec_clear_addr_in_paddr(p_Dtsec->p_MemMap, paddrNum);
  879             p_Dtsec->numOfIndAddrInRegs--;
  880 
  881             return E_OK;
  882         }
  883     }
  884 
  885     RETURN_ERROR(MAJOR, E_NOT_FOUND, NO_MSG);
  886 }
  887 
  888 /* .............................................................................. */
  889 
  890 static t_Error DtsecAddHashMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
  891 {
  892     t_Dtsec         *p_Dtsec = (t_Dtsec *)h_Dtsec;
  893     t_EthHashEntry  *p_HashEntry;
  894     uint64_t        ethAddr;
  895     int32_t         bucket;
  896     uint32_t        crc;
  897     bool            mcast, ghtx;
  898 
  899     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
  900     SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
  901 
  902     ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
  903 
  904     ghtx = (bool)((fman_dtsec_get_rctrl(p_Dtsec->p_MemMap) & RCTRL_GHTX) ? TRUE : FALSE);
  905     mcast = (bool)((ethAddr & MAC_GROUP_ADDRESS) ? TRUE : FALSE);
  906 
  907     if (ghtx && !mcast) /* Cannot handle unicast mac addr when GHTX is on */
  908         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Could not compute hash bucket"));
  909 
  910     crc = GetMacAddrHashCode(ethAddr);
  911 
  912     /* considering the 9 highest order bits in crc H[8:0]:
  913      * if ghtx = 0 H[8:6] (highest order 3 bits) identify the hash register
  914      * and H[5:1] (next 5 bits) identify the hash bit
  915      * if ghts = 1 H[8:5] (highest order 4 bits) identify the hash register
  916      * and H[4:0] (next 5 bits) identify the hash bit.
  917      *
  918      * In bucket index output the low 5 bits identify the hash register bit,
  919      * while the higher 4 bits identify the hash register
  920      */
  921 
  922     if (ghtx)
  923         bucket = (int32_t)((crc >> 23) & 0x1ff);
  924     else {
  925         bucket = (int32_t)((crc >> 24) & 0xff);
  926         /* if !ghtx and mcast the bit must be set in gaddr instead of igaddr. */
  927         if (mcast)
  928             bucket += 0x100;
  929     }
  930 
  931     fman_dtsec_set_bucket(p_Dtsec->p_MemMap, bucket, TRUE);
  932 
  933     /* Create element to be added to the driver hash table */
  934     p_HashEntry = (t_EthHashEntry *)XX_Malloc(sizeof(t_EthHashEntry));
  935     p_HashEntry->addr = ethAddr;
  936     INIT_LIST(&p_HashEntry->node);
  937 
  938     if (ethAddr & MAC_GROUP_ADDRESS)
  939         /* Group Address */
  940         NCSW_LIST_AddToTail(&(p_HashEntry->node), &(p_Dtsec->p_MulticastAddrHash->p_Lsts[bucket]));
  941     else
  942         NCSW_LIST_AddToTail(&(p_HashEntry->node), &(p_Dtsec->p_UnicastAddrHash->p_Lsts[bucket]));
  943 
  944     return E_OK;
  945 }
  946 
  947 /* .............................................................................. */
  948 
  949 static t_Error DtsecDelHashMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
  950 {
  951     t_Dtsec         *p_Dtsec = (t_Dtsec *)h_Dtsec;
  952     t_List          *p_Pos;
  953     t_EthHashEntry  *p_HashEntry = NULL;
  954     uint64_t        ethAddr;
  955     int32_t         bucket;
  956     uint32_t        crc;
  957     bool            mcast, ghtx;
  958 
  959     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
  960     SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
  961 
  962     ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
  963 
  964     ghtx = (bool)((fman_dtsec_get_rctrl(p_Dtsec->p_MemMap) & RCTRL_GHTX) ? TRUE : FALSE);
  965     mcast = (bool)((ethAddr & MAC_GROUP_ADDRESS) ? TRUE : FALSE);
  966 
  967     if (ghtx && !mcast) /* Cannot handle unicast mac addr when GHTX is on */
  968         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Could not compute hash bucket"));
  969 
  970     crc = GetMacAddrHashCode(ethAddr);
  971 
  972     if (ghtx)
  973         bucket = (int32_t)((crc >> 23) & 0x1ff);
  974     else {
  975         bucket = (int32_t)((crc >> 24) & 0xff);
  976         /* if !ghtx and mcast the bit must be set in gaddr instead of igaddr. */
  977         if (mcast)
  978             bucket += 0x100;
  979     }
  980 
  981     if (ethAddr & MAC_GROUP_ADDRESS)
  982     {
  983         /* Group Address */
  984         NCSW_LIST_FOR_EACH(p_Pos, &(p_Dtsec->p_MulticastAddrHash->p_Lsts[bucket]))
  985         {
  986             p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos);
  987             if (p_HashEntry->addr == ethAddr)
  988             {
  989                 NCSW_LIST_DelAndInit(&p_HashEntry->node);
  990                 XX_Free(p_HashEntry);
  991                 break;
  992             }
  993         }
  994         if (NCSW_LIST_IsEmpty(&p_Dtsec->p_MulticastAddrHash->p_Lsts[bucket]))
  995             fman_dtsec_set_bucket(p_Dtsec->p_MemMap, bucket, FALSE);
  996     }
  997     else
  998     {
  999         /* Individual Address */
 1000         NCSW_LIST_FOR_EACH(p_Pos, &(p_Dtsec->p_UnicastAddrHash->p_Lsts[bucket]))
 1001         {
 1002             p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos);
 1003             if (p_HashEntry->addr == ethAddr)
 1004             {
 1005                 NCSW_LIST_DelAndInit(&p_HashEntry->node);
 1006                 XX_Free(p_HashEntry);
 1007                 break;
 1008             }
 1009         }
 1010         if (NCSW_LIST_IsEmpty(&p_Dtsec->p_UnicastAddrHash->p_Lsts[bucket]))
 1011             fman_dtsec_set_bucket(p_Dtsec->p_MemMap, bucket, FALSE);
 1012     }
 1013 
 1014     /* address does not exist */
 1015     ASSERT_COND(p_HashEntry != NULL);
 1016 
 1017     return E_OK;
 1018 }
 1019 
 1020 /* .............................................................................. */
 1021 
 1022 static t_Error DtsecSetPromiscuous(t_Handle h_Dtsec, bool newVal)
 1023 {
 1024     t_Dtsec     *p_Dtsec = (t_Dtsec *)h_Dtsec;
 1025 
 1026     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
 1027     SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
 1028 
 1029     fman_dtsec_set_uc_promisc(p_Dtsec->p_MemMap, newVal);
 1030     fman_dtsec_set_mc_promisc(p_Dtsec->p_MemMap, newVal);
 1031 
 1032     return E_OK;
 1033 }
 1034 
 1035 /* .............................................................................. */
 1036 
 1037 static t_Error DtsecSetStatistics(t_Handle h_Dtsec, e_FmMacStatisticsLevel statisticsLevel)
 1038 {
 1039     t_Dtsec     *p_Dtsec = (t_Dtsec *)h_Dtsec;
 1040     t_Error     err;
 1041 
 1042     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
 1043     SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
 1044 
 1045     p_Dtsec->statisticsLevel = statisticsLevel;
 1046 
 1047     err = (t_Error)fman_dtsec_set_stat_level(p_Dtsec->p_MemMap,
 1048                                         (enum dtsec_stat_level)statisticsLevel);
 1049     if (err != E_OK)
 1050         return err;
 1051 
 1052     switch (statisticsLevel)
 1053     {
 1054     case (e_FM_MAC_NONE_STATISTICS):
 1055             p_Dtsec->exceptions &= ~DTSEC_IMASK_MSROEN;
 1056             break;
 1057     case (e_FM_MAC_PARTIAL_STATISTICS):
 1058             p_Dtsec->exceptions |= DTSEC_IMASK_MSROEN;
 1059             break;
 1060     case (e_FM_MAC_FULL_STATISTICS):
 1061             p_Dtsec->exceptions |= DTSEC_IMASK_MSROEN;
 1062             break;
 1063         default:
 1064             RETURN_ERROR(MINOR, E_INVALID_SELECTION, NO_MSG);
 1065     }
 1066 
 1067     return E_OK;
 1068 }
 1069 
 1070 /* .............................................................................. */
 1071 
 1072 static t_Error DtsecSetWakeOnLan(t_Handle h_Dtsec, bool en)
 1073 {
 1074     t_Dtsec         *p_Dtsec = (t_Dtsec *)h_Dtsec;
 1075 
 1076     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_STATE);
 1077     SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
 1078 
 1079     fman_dtsec_set_wol(p_Dtsec->p_MemMap, en);
 1080 
 1081     return E_OK;
 1082 }
 1083 
 1084 /* .............................................................................. */
 1085 
 1086 static t_Error DtsecAdjustLink(t_Handle h_Dtsec, e_EnetSpeed speed, bool fullDuplex)
 1087 {
 1088     t_Dtsec             *p_Dtsec = (t_Dtsec *)h_Dtsec;
 1089     int                 err;
 1090     enum enet_interface enet_interface;
 1091     enum enet_speed     enet_speed;
 1092 
 1093     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
 1094     SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
 1095 
 1096     p_Dtsec->enetMode = MAKE_ENET_MODE(ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode), speed);
 1097     enet_interface = (enum enet_interface) ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode);
 1098     enet_speed = (enum enet_speed) ENET_SPEED_FROM_MODE(p_Dtsec->enetMode);
 1099     p_Dtsec->halfDuplex = !fullDuplex;
 1100 
 1101     err = fman_dtsec_adjust_link(p_Dtsec->p_MemMap, enet_interface, enet_speed, fullDuplex);
 1102 
 1103     if (err == -EINVAL)
 1104         RETURN_ERROR(MAJOR, E_CONFLICT, ("Ethernet interface does not support Half Duplex mode"));
 1105 
 1106     return (t_Error)err;
 1107 }
 1108 
 1109 /* .............................................................................. */
 1110 
 1111 static t_Error DtsecRestartAutoneg(t_Handle h_Dtsec)
 1112 {
 1113     t_Dtsec      *p_Dtsec = (t_Dtsec *)h_Dtsec;
 1114     uint16_t     tmpReg16;
 1115 
 1116     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
 1117     SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
 1118 
 1119     DTSEC_MII_ReadPhyReg(p_Dtsec, p_Dtsec->tbi_phy_addr, 0, &tmpReg16);
 1120 
 1121     tmpReg16 &= ~( PHY_CR_SPEED0 | PHY_CR_SPEED1 );
 1122     tmpReg16 |= (PHY_CR_ANE | PHY_CR_RESET_AN | PHY_CR_FULLDUPLEX | PHY_CR_SPEED1);
 1123 
 1124     DTSEC_MII_WritePhyReg(p_Dtsec, p_Dtsec->tbi_phy_addr, 0, tmpReg16);
 1125 
 1126     return E_OK;
 1127 }
 1128 
 1129 /* .............................................................................. */
 1130 
 1131 static t_Error DtsecGetId(t_Handle h_Dtsec, uint32_t *macId)
 1132 {
 1133     t_Dtsec     *p_Dtsec = (t_Dtsec *)h_Dtsec;
 1134 
 1135     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
 1136     SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
 1137 
 1138     *macId = p_Dtsec->macId;
 1139 
 1140     return E_OK;
 1141 }
 1142 
 1143 /* .............................................................................. */
 1144 
 1145 static t_Error DtsecGetVersion(t_Handle h_Dtsec, uint32_t *macVersion)
 1146 {
 1147     t_Dtsec     *p_Dtsec = (t_Dtsec *)h_Dtsec;
 1148 
 1149     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
 1150     SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
 1151 
 1152     *macVersion = fman_dtsec_get_revision(p_Dtsec->p_MemMap);
 1153 
 1154     return E_OK;
 1155 }
 1156 
 1157 /* .............................................................................. */
 1158 
 1159 static t_Error DtsecSetException(t_Handle h_Dtsec, e_FmMacExceptions exception, bool enable)
 1160 {
 1161     t_Dtsec     *p_Dtsec = (t_Dtsec *)h_Dtsec;
 1162     uint32_t    bitMask = 0;
 1163 
 1164     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
 1165     SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
 1166 
 1167     if (exception != e_FM_MAC_EX_1G_1588_TS_RX_ERR)
 1168     {
 1169         GET_EXCEPTION_FLAG(bitMask, exception);
 1170         if (bitMask)
 1171         {
 1172             if (enable)
 1173                 p_Dtsec->exceptions |= bitMask;
 1174             else
 1175                 p_Dtsec->exceptions &= ~bitMask;
 1176         }
 1177         else
 1178             RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
 1179 
 1180         if (enable)
 1181             fman_dtsec_enable_interrupt(p_Dtsec->p_MemMap, bitMask);
 1182         else
 1183             fman_dtsec_disable_interrupt(p_Dtsec->p_MemMap, bitMask);
 1184     }
 1185     else
 1186     {
 1187         if (!p_Dtsec->ptpTsuEnabled)
 1188             RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exception valid for 1588 only"));
 1189 
 1190         if (enable)
 1191         {
 1192             p_Dtsec->enTsuErrExeption = TRUE;
 1193             fman_dtsec_enable_tmr_interrupt(p_Dtsec->p_MemMap);
 1194         }
 1195         else
 1196         {
 1197             p_Dtsec->enTsuErrExeption = FALSE;
 1198             fman_dtsec_disable_tmr_interrupt(p_Dtsec->p_MemMap);
 1199         }
 1200     }
 1201 
 1202     return E_OK;
 1203 }
 1204 
 1205 
 1206 /*****************************************************************************/
 1207 /*                      dTSEC Init & Free API                                   */
 1208 /*****************************************************************************/
 1209 
 1210 /* .............................................................................. */
 1211 
 1212 static t_Error DtsecInit(t_Handle h_Dtsec)
 1213 {
 1214     t_Dtsec             *p_Dtsec = (t_Dtsec *)h_Dtsec;
 1215     struct dtsec_cfg    *p_DtsecDriverParam;
 1216     t_Error             err;
 1217     uint16_t            maxFrmLn;
 1218     enum enet_interface enet_interface;
 1219     enum enet_speed     enet_speed;
 1220     t_EnetAddr          ethAddr;
 1221 
 1222     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
 1223     SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
 1224     SANITY_CHECK_RETURN_ERROR(p_Dtsec->fmMacControllerDriver.h_Fm, E_INVALID_HANDLE);
 1225 
 1226     FM_GetRevision(p_Dtsec->fmMacControllerDriver.h_Fm, &p_Dtsec->fmMacControllerDriver.fmRevInfo);
 1227     CHECK_INIT_PARAMETERS(p_Dtsec, CheckInitParameters);
 1228 
 1229     p_DtsecDriverParam  = p_Dtsec->p_DtsecDriverParam;
 1230     p_Dtsec->halfDuplex = p_DtsecDriverParam->halfdup_on;
 1231 
 1232     enet_interface = (enum enet_interface)ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode);
 1233     enet_speed = (enum enet_speed)ENET_SPEED_FROM_MODE(p_Dtsec->enetMode);
 1234     MAKE_ENET_ADDR_FROM_UINT64(p_Dtsec->addr, ethAddr);
 1235 
 1236     err = (t_Error)fman_dtsec_init(p_Dtsec->p_MemMap,
 1237                               p_DtsecDriverParam,
 1238                               enet_interface,
 1239                               enet_speed,
 1240                               (uint8_t*)ethAddr,
 1241                               p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev,
 1242                               p_Dtsec->fmMacControllerDriver.fmRevInfo.minorRev,
 1243                               p_Dtsec->exceptions);
 1244     if (err)
 1245     {
 1246         FreeInitResources(p_Dtsec);
 1247         RETURN_ERROR(MAJOR, err, ("This DTSEC version does not support the required i/f mode"));
 1248     }
 1249 
 1250     if (ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode) == e_ENET_IF_SGMII)
 1251     {
 1252         uint16_t            tmpReg16;
 1253 
 1254         /* Configure the TBI PHY Control Register */
 1255         tmpReg16 = PHY_TBICON_CLK_SEL | PHY_TBICON_SRESET;
 1256         DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 17, tmpReg16);
 1257 
 1258         tmpReg16 = PHY_TBICON_CLK_SEL;
 1259         DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 17, tmpReg16);
 1260 
 1261         tmpReg16 = (PHY_CR_PHY_RESET | PHY_CR_ANE | PHY_CR_FULLDUPLEX | PHY_CR_SPEED1);
 1262         DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 0, tmpReg16);
 1263 
 1264         if (p_Dtsec->enetMode & ENET_IF_SGMII_BASEX)
 1265             tmpReg16 = PHY_TBIANA_1000X;
 1266         else
 1267             tmpReg16 = PHY_TBIANA_SGMII;
 1268         DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 4, tmpReg16);
 1269 
 1270         tmpReg16 = (PHY_CR_ANE | PHY_CR_RESET_AN | PHY_CR_FULLDUPLEX | PHY_CR_SPEED1);
 1271 
 1272         DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 0, tmpReg16);
 1273     }
 1274 
 1275     /* Max Frame Length */
 1276     maxFrmLn = fman_dtsec_get_max_frame_len(p_Dtsec->p_MemMap);
 1277     err = FmSetMacMaxFrame(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MAC_1G,
 1278             p_Dtsec->fmMacControllerDriver.macId, maxFrmLn);
 1279     if (err)
 1280         RETURN_ERROR(MINOR,err, NO_MSG);
 1281 
 1282     p_Dtsec->p_MulticastAddrHash = AllocHashTable(EXTENDED_HASH_TABLE_SIZE);
 1283     if (!p_Dtsec->p_MulticastAddrHash) {
 1284         FreeInitResources(p_Dtsec);
 1285         RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MC hash table is FAILED"));
 1286     }
 1287 
 1288     p_Dtsec->p_UnicastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
 1289     if (!p_Dtsec->p_UnicastAddrHash)
 1290     {
 1291         FreeInitResources(p_Dtsec);
 1292         RETURN_ERROR(MAJOR, E_NO_MEMORY, ("UC hash table is FAILED"));
 1293     }
 1294 
 1295     /* register err intr handler for dtsec to FPM (err)*/
 1296     FmRegisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm,
 1297                    e_FM_MOD_1G_MAC,
 1298                    p_Dtsec->macId,
 1299                    e_FM_INTR_TYPE_ERR,
 1300                    DtsecIsr,
 1301                    p_Dtsec);
 1302     /* register 1588 intr handler for TMR to FPM (normal)*/
 1303     FmRegisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm,
 1304                    e_FM_MOD_1G_MAC,
 1305                    p_Dtsec->macId,
 1306                    e_FM_INTR_TYPE_NORMAL,
 1307                    Dtsec1588Isr,
 1308                    p_Dtsec);
 1309     /* register normal intr handler for dtsec to main interrupt controller. */
 1310     if (p_Dtsec->mdioIrq != NO_IRQ)
 1311     {
 1312         XX_SetIntr(p_Dtsec->mdioIrq, DtsecMdioIsr, p_Dtsec);
 1313         XX_EnableIntr(p_Dtsec->mdioIrq);
 1314     }
 1315 
 1316     XX_Free(p_DtsecDriverParam);
 1317     p_Dtsec->p_DtsecDriverParam = NULL;
 1318 
 1319     err = DtsecSetStatistics(h_Dtsec, e_FM_MAC_FULL_STATISTICS);
 1320     if (err)
 1321     {
 1322         FreeInitResources(p_Dtsec);
 1323         RETURN_ERROR(MAJOR, err, ("Undefined statistics level"));
 1324     }
 1325 
 1326     return E_OK;
 1327 }
 1328 
 1329 /* ........................................................................... */
 1330 
 1331 static t_Error DtsecFree(t_Handle h_Dtsec)
 1332 {
 1333     t_Dtsec      *p_Dtsec = (t_Dtsec *)h_Dtsec;
 1334 
 1335     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
 1336 
 1337     if (p_Dtsec->p_DtsecDriverParam)
 1338     {
 1339         /* Called after config */
 1340         XX_Free(p_Dtsec->p_DtsecDriverParam);
 1341         p_Dtsec->p_DtsecDriverParam = NULL;
 1342     }
 1343     else
 1344         /* Called after init */
 1345         FreeInitResources(p_Dtsec);
 1346 
 1347     XX_Free(p_Dtsec);
 1348 
 1349     return E_OK;
 1350 }
 1351 
 1352 /* .............................................................................. */
 1353 
 1354 static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacControllerDriver)
 1355 {
 1356     p_FmMacControllerDriver->f_FM_MAC_Init                      = DtsecInit;
 1357     p_FmMacControllerDriver->f_FM_MAC_Free                      = DtsecFree;
 1358 
 1359     p_FmMacControllerDriver->f_FM_MAC_SetStatistics             = DtsecSetStatistics;
 1360     p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback            = DtsecConfigLoopback;
 1361     p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength      = DtsecConfigMaxFrameLength;
 1362 
 1363     p_FmMacControllerDriver->f_FM_MAC_ConfigWan                 = NULL; /* Not supported on dTSEC */
 1364 
 1365     p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc           = DtsecConfigPadAndCrc;
 1366     p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex          = DtsecConfigHalfDuplex;
 1367     p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck         = DtsecConfigLengthCheck;
 1368     p_FmMacControllerDriver->f_FM_MAC_ConfigTbiPhyAddr          = DtsecConfigTbiPhyAddr;
 1369     p_FmMacControllerDriver->f_FM_MAC_ConfigException           = DtsecConfigException;
 1370     p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit         = NULL;
 1371 
 1372     p_FmMacControllerDriver->f_FM_MAC_Enable                    = DtsecEnable;
 1373     p_FmMacControllerDriver->f_FM_MAC_Disable                   = DtsecDisable;
 1374     p_FmMacControllerDriver->f_FM_MAC_Resume                    = NULL;
 1375 
 1376     p_FmMacControllerDriver->f_FM_MAC_SetException              = DtsecSetException;
 1377 
 1378     p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous            = DtsecSetPromiscuous;
 1379     p_FmMacControllerDriver->f_FM_MAC_AdjustLink                = DtsecAdjustLink;
 1380     p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan              = DtsecSetWakeOnLan;
 1381     p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg            = DtsecRestartAutoneg;
 1382 
 1383     p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp       = DtsecEnable1588TimeStamp;
 1384     p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp      = DtsecDisable1588TimeStamp;
 1385 
 1386     p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames      = DtsecTxMacPause;
 1387     p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames          = DtsecSetTxPauseFrames;
 1388     p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames    = DtsecRxIgnoreMacPause;
 1389 
 1390     p_FmMacControllerDriver->f_FM_MAC_ResetCounters             = DtsecResetCounters;
 1391     p_FmMacControllerDriver->f_FM_MAC_GetStatistics             = DtsecGetStatistics;
 1392 
 1393     p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr             = DtsecModifyMacAddress;
 1394     p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr            = DtsecAddHashMacAddress;
 1395     p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr         = DtsecDelHashMacAddress;
 1396     p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr      = DtsecAddExactMatchMacAddress;
 1397     p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr  = DtsecDelExactMatchMacAddress;
 1398     p_FmMacControllerDriver->f_FM_MAC_GetId                     = DtsecGetId;
 1399     p_FmMacControllerDriver->f_FM_MAC_GetVersion                = DtsecGetVersion;
 1400     p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength         = DtsecGetMaxFrameLength;
 1401 
 1402     p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg           = DTSEC_MII_WritePhyReg;
 1403     p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg            = DTSEC_MII_ReadPhyReg;
 1404 
 1405 }
 1406 
 1407 
 1408 /*****************************************************************************/
 1409 /*                      dTSEC Config Main Entry                             */
 1410 /*****************************************************************************/
 1411 
 1412 /* .............................................................................. */
 1413 
 1414 t_Handle  DTSEC_Config(t_FmMacParams *p_FmMacParam)
 1415 {
 1416     t_Dtsec             *p_Dtsec;
 1417     struct dtsec_cfg    *p_DtsecDriverParam;
 1418     uintptr_t           baseAddr;
 1419 
 1420     SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_NULL_POINTER, NULL);
 1421 
 1422     baseAddr = p_FmMacParam->baseAddr;
 1423 
 1424     /* allocate memory for the UCC GETH data structure. */
 1425     p_Dtsec = (t_Dtsec *)XX_Malloc(sizeof(t_Dtsec));
 1426     if (!p_Dtsec)
 1427     {
 1428         REPORT_ERROR(MAJOR, E_NO_MEMORY, ("dTSEC driver structure"));
 1429         return NULL;
 1430     }
 1431     memset(p_Dtsec, 0, sizeof(t_Dtsec));
 1432     InitFmMacControllerDriver(&p_Dtsec->fmMacControllerDriver);
 1433 
 1434     /* allocate memory for the dTSEC driver parameters data structure. */
 1435     p_DtsecDriverParam = (struct dtsec_cfg *) XX_Malloc(sizeof(struct dtsec_cfg));
 1436     if (!p_DtsecDriverParam)
 1437     {
 1438         XX_Free(p_Dtsec);
 1439         REPORT_ERROR(MAJOR, E_NO_MEMORY, ("dTSEC driver parameters"));
 1440         return NULL;
 1441     }
 1442     memset(p_DtsecDriverParam, 0, sizeof(struct dtsec_cfg));
 1443 
 1444     /* Plant parameter structure pointer */
 1445     p_Dtsec->p_DtsecDriverParam = p_DtsecDriverParam;
 1446 
 1447     fman_dtsec_defconfig(p_DtsecDriverParam);
 1448 
 1449     p_Dtsec->p_MemMap           = (struct dtsec_regs *)UINT_TO_PTR(baseAddr);
 1450     p_Dtsec->p_MiiMemMap        = (struct dtsec_mii_reg *)UINT_TO_PTR(baseAddr + DTSEC_TO_MII_OFFSET);
 1451     p_Dtsec->addr               = ENET_ADDR_TO_UINT64(p_FmMacParam->addr);
 1452     p_Dtsec->enetMode           = p_FmMacParam->enetMode;
 1453     p_Dtsec->macId              = p_FmMacParam->macId;
 1454     p_Dtsec->exceptions         = DEFAULT_exceptions;
 1455     p_Dtsec->mdioIrq            = p_FmMacParam->mdioIrq;
 1456     p_Dtsec->f_Exception        = p_FmMacParam->f_Exception;
 1457     p_Dtsec->f_Event            = p_FmMacParam->f_Event;
 1458     p_Dtsec->h_App              = p_FmMacParam->h_App;
 1459     p_Dtsec->ptpTsuEnabled      = p_Dtsec->p_DtsecDriverParam->ptp_tsu_en;
 1460     p_Dtsec->enTsuErrExeption   = p_Dtsec->p_DtsecDriverParam->ptp_exception_en;
 1461     p_Dtsec->tbi_phy_addr       = p_Dtsec->p_DtsecDriverParam->tbi_phy_addr;
 1462 
 1463     return p_Dtsec;
 1464 }

Cache object: 3424d28bd0007b5a10bf206f5dc21b49


[ 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.